// Description:
// Output:
// Modify: 
void 
Authenticator_StateAUTHENTICATION(
	IN	PADAPTER		Adapter,
	IN	PRT_WLAN_STA	pSTA
	)
{
	if( !ACTING_AS_AP(Adapter) )
	{
		RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("[Warning] current: STA mode, return."));
		return;
	}

	pSTA->perSTAKeyInfo.PrState = ASMPS_AUTHENTICATION;

	// [AnnieTODO]
	// 1. GNoStations ++
	// 2. PTK = 0
	PlatformZeroMemory( pSTA->perSTAKeyInfo.PTK, PTK_LEN);

	PlatformZeroMemory(pSTA->perSTAKeyInfo.AESKeyBuf, AESCCMP_BLK_SIZE_TOTAL);
	//pSTA->perSTAKeyInfo.bPTKInstalled = FALSE;
	pSTA->perSTAKeyInfo.PInitAKeys = FALSE;

	// 3. 802.1x::PortControl = Auto
	pSTA->perSTAKeyInfo.portControl = pct_Auto;

	// 4. 802.1x::PortMode = Enabled
	pSTA->perSTAKeyInfo.portMode = pmt_Enable;
	
	// UCT
	Authenticator_StateAUTHENTICATION2( Adapter, pSTA );
}
//
//	Description:
//		Allocate memory for driver log mechansim. 
//
//	Assumption:
//		Target address had been initalized to NULL pointer.
//
BOOLEAN
AllocDrvLogMemory(
	IN	PADAPTER		pAdapter
	)
{
	u4Byte i;
	RT_STATUS status;
	PVOID pTmp;
	u4Byte Size;

	//
	// Allocate memory block to store pointers to DRV_LOG_POOL_T objects.
	//
	Size = LTYPE_TOTAL_COUNT * sizeof(PVOID);
	status = PlatformAllocateMemory(pAdapter, &pTmp, Size);
	if( RT_STATUS_SUCCESS != status )
	{
		RT_TRACE(COMP_INIT, DBG_SERIOUS, ("AllocDrvLogMemory(): failed to allocate DRV_LOG_POOLS_HANDLE!!!\n"));
		return FALSE;
	}
	else
	{
		RT_TRACE(COMP_INIT, DBG_LOUD, ("AllocDrvLogMemory(): %p is allocated for DRV_LOG_POOLS_HANDLE\n", pTmp));
		PlatformZeroMemory(pTmp, Size);
		SET_DRV_LOG_POOLS_HANDLE(pAdapter, (DRV_LOG_POOL_T**)pTmp);
	}

	//
	// Allocate DRV_LOG_POOL_T objects.
	//
	for(i = 0; i < (u4Byte)LTYPE_TOTAL_COUNT; i++)
	{
		Size = sizeof(DRV_LOG_POOL_T) + ( sizeof(DRV_LOG_DATA_IMP_T) << g_LogTypes[i].MaxLogCountPwr); 
		status = PlatformAllocateMemory(pAdapter, &pTmp, Size);
		if( RT_STATUS_SUCCESS != status )
		{
			RT_TRACE(COMP_INIT, DBG_SERIOUS, ("AllocDrvLogMemory(): failed driver log pool %d!!!\n", i));
			return FALSE;
		}
		else
		{
			RT_TRACE(COMP_INIT, DBG_LOUD, ("AllocDrvLogMemory(): %p is allocated for driver log pool %d\n", pTmp, i));
			PlatformZeroMemory(pTmp, Size);
			SET_DRV_LOG_POOL(pAdapter, i, pTmp);
			GET_DRV_LOG_POOL(pAdapter, i)->pLogDataRing = (PDRV_LOG_DATA_IMP_T)((pu1Byte)pTmp + sizeof(DRV_LOG_POOL_T)); 

			RT_PRINT_DATA(COMP_INIT, DBG_TRACE, "driver log pool: ", (pu1Byte)pTmp, sizeof(DRV_LOG_POOL_T));
		}
	}
	
	return TRUE;
}
VOID
p2p_IndicateActionFrameReceived(
	IN  P2P_INFO				*pP2PInfo,
	IN  u4Byte					eventId,
	IN  RT_STATUS				rtStatus,
	IN  u1Byte					*pFrameBuf,
	IN  u4Byte					frameLen
	)
{
	P2P_EVENT_DATA			eventData;

	PlatformZeroMemory(&eventData, sizeof(P2P_EVENT_DATA));

	if(RT_STATUS_SUCCESS == rtStatus)
	{
		eventData.Packet.Buffer = pFrameBuf;
		eventData.Packet.Length = frameLen;
	}
	else
	{
		eventData.rtStatus = rtStatus;
	}

	p2p_IndicateEvent(pP2PInfo, eventId, &eventData);

	return;
}
VOID
p2p_channel_IntersectRegClass(
	IN  const P2P_REG_CLASS		*a,
	IN  const P2P_REG_CLASS		*b,
	OUT P2P_REG_CLASS			*res
	)
{
	u1Byte						ita = 0;
	u1Byte						itb = 0;

	PlatformZeroMemory(res, sizeof(*res));

	res->regClass = a->regClass;
	res->channels = 0;

	for(ita = 0; ita < a->channels; ita++)
	{
		for(itb = 0; itb < b->channels; itb++)
		{
			if(a->channel[ita] != b->channel[itb])
				continue;
			
			res->channel[res->channels++] = a->channel[ita];
			if(P2P_MAX_REG_CLASS_CHANNELS == res->channels)
				return;
		}
	}
}
VOID
p2p_Channel_Reset(
	IN  P2P_CHANNELS			*channels
	)
{
	PlatformZeroMemory(channels, sizeof(*channels));

	return;
}
RT_STATUS
MultiPortPrepareCloneRfd(
	PADAPTER	pAdapter
)
{
	RT_STATUS rtStatus = RT_STATUS_FAILURE;
	PRT_RFD	 pRfd = NULL;
	u4Byte i = 0;
	PMULTIPORT_COMMON_CONTEXT pMultiPortCommon = MultiPortGetCommonContext(pAdapter);
		
	const u4Byte SIZE_OF_CLONE_RFD_QUEUE = 256;

	do
	{
		// Allocate memory for the Multiport Clone RFD -------------------------------------------------
		pMultiPortCommon->CloneRfdMemoryBuffer.Length = SIZE_OF_CLONE_RFD_QUEUE * sizeof(RT_RFD);

		rtStatus = PlatformAllocateMemory(pAdapter, 
				&pMultiPortCommon->CloneRfdMemoryBuffer.Buffer,
				pMultiPortCommon->CloneRfdMemoryBuffer.Length
			);

		if(rtStatus != RT_STATUS_SUCCESS)
		{
			RT_TRACE(COMP_INIT, DBG_SERIOUS, ("%s: MultiPort Clone RFD: Memory Allocation Failure !\n", __FUNCTION__));
			break;
		}
		// ---------------------------------------------------------------------------------------

		// Insert the Clone RFDs into the queue --------------------------------------------------------
		pMultiPortCommon->uNumberOfCloneRfds = SIZE_OF_CLONE_RFD_QUEUE;

		PlatformZeroMemory(
				pMultiPortCommon->CloneRfdMemoryBuffer.Buffer, 
				pMultiPortCommon->CloneRfdMemoryBuffer.Length
			);
		PlatformAcquireSpinLock(pAdapter,RT_RFD_SPINLOCK);
		pRfd = (PRT_RFD) pMultiPortCommon->CloneRfdMemoryBuffer.Buffer;
		
		for(i = 0; i < pMultiPortCommon->uNumberOfCloneRfds; i++)
		{
			RTInsertTailListWithCnt(
					&pMultiPortCommon->CloneRfdIdleQueue, 
					&pRfd[i].List, 
					&pMultiPortCommon->uCloneRfdIdleQueueSize
				);
		}
		RT_TRACE(COMP_INIT, DBG_LOUD, ("MultiPortPrepareCloneRfd(), pMultiPortCommon->uCloneRfdIdleQueueSize = %d\n",
			pMultiPortCommon->uCloneRfdIdleQueueSize));
		PlatformReleaseSpinLock(pAdapter,RT_RFD_SPINLOCK);
		// ---------------------------------------------------------------------------------------
	} while(FALSE);

	return rtStatus;
}
PADAPTER
MultiPortFeedPacketToMultipleAdapter(
	PADAPTER	pAdapter,
	PRT_RFD		pRfd
)
{
	// NOTE: --------------------------------------------------------------
	//  If only single adapter is needed, return that adapter.
	// --------------------------------------------------------------------

	PADAPTER pDefaultAdapter = GetDefaultAdapter(pAdapter);
	PMULTIPORT_COMMON_CONTEXT pMultiPortCommon = MultiPortGetCommonContext(pDefaultAdapter);
	PADAPTER pExtAdapter = NULL;
	PRT_RFD pExtRfd = NULL;
	u4Byte i = 0;
	RT_STATUS rtStatus = RT_STATUS_SUCCESS;
	
	// Assertion Check Variable
	u4Byte uCurrentCloneRFDs;
	
	// Target List 
	u4Byte uTargetAdapter = 0;
	PADAPTER TargetList[10];


	// Single MPDU
	OCTET_STRING frame = {NULL, 0};
	FillOctetString(frame, pRfd->Buffer.VirtualAddress, pRfd->PacketLength);

	if(pRfd->Status.bHwError)
	{
		RT_TRACE(COMP_RECV, DBG_TRACE, ("MultiPortFeedPacketToMultipleAdapter(): Return because bHwError is true.\n"));
		return NULL;
	}

	// Information Source: pRfd Status Checking -------------------------------------------------------
	RT_ASSERT(pRfd->Buffer.VirtualAddress != NULL, ("Error: pRfd->Buffer.VirtualAddress is NULL!\n"));
	RT_ASSERT(pRfd->Buffer.Length != 0, ("Error: pRfd->Buffer.Length is 0!\n"));
	RT_ASSERT(pRfd->PacketLength <= pRfd->Buffer.Length, ("Error: Packet Too Long!\n"));
	// ------------------------------------------------------------------------------------------

	// Clone RFD Status Checking ----------------------------------------------------------------------------------------------------------------------
	PlatformAcquireSpinLock(pDefaultAdapter, RT_RFD_SPINLOCK);
	uCurrentCloneRFDs = pMultiPortCommon->uCloneRfdIdleQueueSize + pMultiPortCommon->uCloneRfdBusyQueueSize;
	RT_ASSERT(uCurrentCloneRFDs == pMultiPortCommon->uNumberOfCloneRfds, 	("Failure: Some Clone RFDs are Lost!uCurrentCloneRFDs=%d\n", uCurrentCloneRFDs));
	PlatformReleaseSpinLock(pDefaultAdapter, RT_RFD_SPINLOCK);
	// ---------------------------------------------------------------------------------------------------------------------------------------------


	// Get the target adapter list -----------------------------------------------------------------------------
	uTargetAdapter = MultiPortGetTargetAdapterList(pAdapter, pRfd, frame, TargetList, sizeof(TargetList) / sizeof(PADAPTER));
	//RT_TRACE(COMP_INIT, DBG_TRACE, ("%s: uTargetAdapter: %d \n", __FUNCTION__, uTargetAdapter));
	
	if(uTargetAdapter == 0)
	{
		// Free the original RFD since the RFD is not necessary
		RT_TRACE(COMP_INIT, DBG_TRACE, ("%s: No Target Adapter Found!\n", __FUNCTION__));
		return NULL;
	}
	else if(uTargetAdapter == 1)
	{
		// Single adapter is needed. Do not free the original RFD, and run the original path
		return TargetList[0];
	}
	// ----------------------------------------------------------------------------------------------------


	// Send to each adapter
	for(i = 0; i < uTargetAdapter; i++)
	{
		// Get the target adapter element
		pExtAdapter = TargetList[i];

		PlatformAcquireSpinLock(pDefaultAdapter, RT_RFD_SPINLOCK);
		if(RTIsListEmpty(&pMultiPortCommon->CloneRfdIdleQueue))
		{			
			PlatformReleaseSpinLock(pDefaultAdapter, RT_RFD_SPINLOCK);
			RT_TRACE(COMP_INIT, DBG_SERIOUS, ("%s: No enough Clone RFD!\n", __FUNCTION__));
			break;
		}

		// Acquire an idle Clone RFD and initialize the Clone RFD -----------------------------------------
		pExtRfd = (PRT_RFD) RTRemoveHeadListWithCnt(
				&pMultiPortCommon->CloneRfdIdleQueue, 
				&pMultiPortCommon->uCloneRfdIdleQueueSize
			);

		// + Clone the original information
		PlatformZeroMemory(pExtRfd, sizeof(RT_RFD));
		PlatformMoveMemory(pExtRfd, pRfd, sizeof(RT_RFD));	

		// + Record the needed memory length 
		pExtRfd->mbCloneRfdDataBuffer.Length = pRfd->Buffer.Length;

		// + Allocate the memory based on the needed memory length above
		rtStatus = DrvIFAssociateRFD(pDefaultAdapter, pExtRfd);
		
		if(rtStatus != RT_STATUS_SUCCESS)
		{
			// Return the CloneRFD resource
			RTInsertTailListWithCnt(
				&pMultiPortCommon->CloneRfdIdleQueue, 
				&pExtRfd->List, 
				&pMultiPortCommon->uCloneRfdIdleQueueSize
			);
			PlatformReleaseSpinLock(pDefaultAdapter, RT_RFD_SPINLOCK);
			//RT_TRACE(COMP_INIT, DBG_SERIOUS, ("%s: No enough memory!\n", __FUNCTION__));
			break;
		}

		//Sinda 20150903, Should assign Buffer's address according to it is clone RFD.
		if(IsCloneRFD(pDefaultAdapter, pExtRfd))
		{
			// + Attach the memory to the CloneRFD
			pExtRfd->Buffer.VirtualAddress = pExtRfd->mbCloneRfdDataBuffer.Buffer;
			pExtRfd->Buffer.Length = pExtRfd->mbCloneRfdDataBuffer.Length;
		}

#if RX_AGGREGATION
		//   + No Next RFD
		pExtRfd->NextRfd = NULL;

		//  + Only Single MPDU Packet
		pExtRfd->nTotalFrag = 1;

		//   + No Parent RFD
		pExtRfd->ParentRfd = NULL;

		//   + Not in the USB temp RFD list: pAdapter->RfdTmpList
		pExtRfd->bIsTemp = FALSE;
#endif

		//	Please be careful to handle pRfd->Buffer.VirtualAddress offset.
		//	+ Move data
		PlatformMoveMemory(
				pExtRfd->Buffer.VirtualAddress,
				pRfd->Buffer.VirtualAddress - pAdapter->HalFunc.GetRxPacketShiftBytesHandler(pRfd), 
				(pRfd->PacketLength + pAdapter->HalFunc.GetRxPacketShiftBytesHandler(pRfd))>pAdapter->MAX_RECEIVE_BUFFER_SIZE? pAdapter->MAX_RECEIVE_BUFFER_SIZE:(pRfd->PacketLength + pAdapter->HalFunc.GetRxPacketShiftBytesHandler(pRfd))
			);

		//   + Get shifted bytes of starting address of 802.11 header (Sync the memory offset)
		pExtRfd->Buffer.VirtualAddress += pAdapter->HalFunc.GetRxPacketShiftBytesHandler(pRfd);
	 	// -------------------------------------------------------------------------------------

		// Insert into busy Clone RFD queue
		RTInsertHeadListWithCnt(
				&pMultiPortCommon->CloneRfdBusyQueue, 
				&pExtRfd->List, 
				&pMultiPortCommon->uCloneRfdBusyQueueSize
			);

		PlatformReleaseSpinLock(pDefaultAdapter, RT_RFD_SPINLOCK);
		// Iteration Flag
		pExtRfd->bFeedPacketToSingleAdapter = TRUE;

		// The pExtRfd will be free in ProcessReceivedPacket()
		ProcessReceivedPacketForEachPortSpecific(pExtAdapter, pExtRfd);
	}


	// Free the original RFD since the CloneRFD is adopted.
	return NULL;
}
void 
Authenticator_StateINITIALIZE(
	IN	PADAPTER		Adapter,
	IN	PRT_WLAN_STA	pSTA
	)
{
	PAUTH_PKEY_MGNT_TAG	pKeyMgnt = &pSTA->perSTAKeyInfo;
	u1Byte	RdmBuf[20], NonceBuf[KEY_NONCE_LEN];
	u1Byte	i = 0;

	pKeyMgnt->pWLanSTA = pSTA;

	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("===> Authenticator_StateINITIALIZE()\n") );

	if( !ACTING_AS_AP(Adapter)
		&& !GET_TDLS_ENABLED(&(Adapter->MgntInfo)) 
		)
	{
		RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("[Warning] current: STA mode, return."));
		return;
	}

	PlatformZeroMemory( pKeyMgnt->SNonce, KEY_NONCE_LEN );

	pKeyMgnt->TimeoutCtr = 0;
	pKeyMgnt->TimeSlot_sendstart = 0;
	pKeyMgnt->TimeSlot_lastsend = 0;

	if( Adapter->MgntInfo.SecurityInfo.AuthMode == RT_802_11AuthModeWPAPSK )
	{
		// 3. 802.1x::PortMode = Disable;
		pKeyMgnt->portMode = pmt_Disable;	// [TODO] other auth mode
		
		// 4. 802.1x::PortSecure = 0;
		pKeyMgnt->portSecure= psec_Unauthorized;	// [TODO] other auth mode
	}

	
	// 1. MSK = 0 ...?
	
	// 2. GNoStations = 0
	//	...it's for group key update. I don't do it currently. Annie, 2005-07-01.

	// Rest ANonce
	GetRandomBuffer( RdmBuf );
	for( i=0; i<16; i++ )
	{
		NonceBuf[i] = RdmBuf[i];
		NonceBuf[16+i] = RdmBuf[19-i];
	}

	PlatformMoveMemory( pKeyMgnt->ANonce , NonceBuf , KEY_NONCE_LEN );

	
	// 5. RemovePTK
	PlatformZeroMemory( pKeyMgnt->PTK, PTK_LEN );

	pKeyMgnt->TempEncKey = NULL;
	pKeyMgnt->TxMICKey   = NULL;
	pKeyMgnt->RxMICKey   = NULL;

	//AP-WPA AES ,CCW
	PlatformZeroMemory( pKeyMgnt->AESKeyBuf , AESCCMP_BLK_SIZE_TOTAL );
	
	//pKeyMgnt->bPTKInstalled = FALSE;
	pKeyMgnt->PInitAKeys = FALSE;
	pKeyMgnt->GInitAKeys = FALSE;
	pKeyMgnt->Pair = TRUE;				// [AnnieNote] Why not FALSE?? 2005-07-18.

	// TODO: 6. Revome key from CAM
	// [AnnieNote]
	// (1) We can only clear the MAC address (instead of total 6 double-word) in per CAM entry.
	// (2) When called by Authenticator_GlobalReset(), it takes a lot of I/O, and is H/W depended.
	//       Should we do it here? Or use workitem... ?

	//Remove  key from SW/HW CAM table, Add by CCW
	AP_RemoveKey( Adapter , pSTA );
	
	// 7. Reset ReplayCounter
	pKeyMgnt->KeyReplayCounter = 0;
	
	// 8. Reset SNonce
	PlatformZeroMemory( pKeyMgnt->SNonce, KEY_NONCE_LEN );

	// 9. Initialize TimeSlot_lastIntegrityFailed.
	pKeyMgnt->TimeSlot_lastIntegrityFailed = 0;

	pKeyMgnt->RxIV   = DEFAULT_INIT_RX_IV;
	pKeyMgnt->TxIV   = DEFAULT_INIT_TX_IV;
	pKeyMgnt->KeyRSC = pKeyMgnt->TxIV; 

	// Added by Annie for debug, 2005-07-25.
	pKeyMgnt->MicErrorCnt = 0;
	pKeyMgnt->WEPErrorCnt = 0;

	pKeyMgnt->PrState = ASMPS_INITIALIZE;
	pKeyMgnt->GrState = ASMGS_INITIALIZE;


	pSTA->keyindex = 0;

	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("<=== Authenticator_StateINITIALIZE()\n") );

}
// Description: Initialize the global key data in Authenticator.
// Output: void
// Modify: Annie, 2005-07-02
//		I check the data struct again, and discard using pMgntInfo->globalKeyInfo.groupKeyInfo.
//		Now Global/group key data (PMK, GTK, ANonce): all kept in pMgntInfo->globalKeyInfo.
//		global key state: recorded in pEntry->perSTAKeyInfo.GrState. (I think it should be kept in per station.)
//
void 
Authenticator_GlobalReset(
	IN	PADAPTER		Adapter
	)
{
	PMGNT_INFO	pMgntInfo = &Adapter->MgntInfo;
	PRT_SECURITY_T	pSecInfo = &(pMgntInfo->SecurityInfo);
	PAUTH_GLOBAL_KEY_TAG	pGlInfo = &(pMgntInfo->globalKeyInfo);
	PRT_WLAN_STA	pEntry;
	int 		i;
	u1Byte	RdmBuf[20], NonceBuf[KEY_NONCE_LEN];
	static u1Byte	CAM_CONST_BROAD[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
	AESCCMP_BLOCK		blockKey;	


	//--- [AnnieWorkaround] See 11i D3.0 page91, GTK should be generated by PRF-X.
	u1Byte	TmpGTK[] = "12345678123456781234567812345678";
	//---

	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("===> Authenticator_GlobalReset()\n") );

	if( !ACTING_AS_AP(Adapter) )
	{
		RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("[Warning] current: STA mode, return."));
		return;
	}

	pGlInfo->currentId = 0;

	if(pSecInfo->SecLvl == RT_SEC_LVL_WPA)
		pGlInfo->DescriptorType = desc_type_RSN;
	else
		pGlInfo->DescriptorType = desc_type_WPA2;

	GetRandomBuffer( RdmBuf );
	for( i=0; i<16; i++ )
	{
		NonceBuf[i] = RdmBuf[i];
		NonceBuf[16+i] = RdmBuf[19-i];
	}
	NonceBuf[KEY_NONCE_LEN-1] = 0;	//[AnnieWorkaround] Remove it if ANonce addition is ready. 2005-11-25.
	RT_PRINT_DATA( COMP_AUTHENTICATOR, DBG_LOUD, "Authenticator_GlobalReset(): NonceBuf", NonceBuf, KEY_NONCE_LEN );	

	// 1. Install PMK
	if( pGlInfo->PassphraseLen < 64 ){
	PasswordHash(pGlInfo->Passphrase, pGlInfo->PassphraseLen,
		pMgntInfo->Ssid.Octet, pMgntInfo->Ssid.Length, pGlInfo->PMK );
	}
	else
	{
		// Add for direct to set PMK 64-Hex mode...
		if( pGlInfo->PassphraseLen == 64 )
			PlatformMoveMemory(pGlInfo->PMK, pGlInfo->Passphrase , 32 );
	}
	// 2. Install GTK

        //
        // 2010/12/15 Neo Jou check in
        // When in Linux AP mode, hostapd will set down GTK before Authenticator_GlobalReset()
        // Thus for Linux AP mode case, we don't reset GTK here
        //
	PlatformZeroMemory( pGlInfo->GTK, GTK_LEN );
	PlatformMoveMemory( pGlInfo->GTK, TmpGTK, GTK_LEN );
	pGlInfo->TxMICKey = pGlInfo->GTK + GTK_MIC_TX_POS;
	pGlInfo->RxMICKey = pGlInfo->GTK + GTK_MIC_RX_POS;

	//AP WPA AES,CCW	
	PlatformMoveMemory( blockKey.x , pGlInfo->GTK , 16);
	AES_SetKey(blockKey.x, AESCCMP_BLK_SIZE*8, (pu4Byte)pGlInfo->AESGTK);
	//
	pSecInfo->GroupTransmitKeyIdx = 1;
	
			

	// 3. Install ANonce
//	CopyMem( pGlInfo->ANonce, NonceBuf, KEY_NONCE_LEN );
	PlatformMoveMemory(pGlInfo->ANonce, NonceBuf, KEY_NONCE_LEN );

	// 4. Install GNonce
//	CopyMem( pGlInfo->GNonce, NonceBuf, KEY_NONCE_LEN );
	PlatformMoveMemory(pGlInfo->GNonce, NonceBuf, KEY_NONCE_LEN );

	// 5. Reset KeyRSC
	pGlInfo->KeyRSC = 0;
	
	// 6. Reset time slot.
	pGlInfo->CurrentTimeSlot = 0;

#if 1 //Addedby Jay 0713
	pGlInfo->TimeSlot_IntegrityFail2 = 0;
#endif

	// 7. IV
#if 1 //Added by Jay 0712 for security IV
	pSecInfo->TxIV = DEFAULT_INIT_TX_IV;
#endif
	pMgntInfo->bAPGlobRest = TRUE;
	// Reset key information of each station.
	for(i = 0; i < ASSOCIATE_ENTRY_NUM; i++)
	{
		pEntry = &(pMgntInfo->AsocEntry[i]);
		Authenticator_StateINITIALIZE(Adapter, pEntry);
	}
	pMgntInfo->bAPGlobRest = FALSE;

	//reset SWCamTabe and HWCamtable ,add by CCW
	AP_ClearAllKey(Adapter);
	
	if( (MgntActQuery_ApType(Adapter) == RT_AP_TYPE_NORMAL ||
	MgntActQuery_ApType(Adapter) == RT_AP_TYPE_IBSS_EMULATED 
		 || MgntActQuery_ApType(Adapter) == RT_AP_TYPE_LINUX) && 
     	( pMgntInfo->NdisVersion  < RT_NDIS_VERSION_6_20 ))
	{
	switch( pSecInfo->PairwiseEncAlgorithm )
	{
	case RT_ENC_ALG_TKIP:
		AP_Setkey(  Adapter , 
			     CAM_CONST_BROAD,
			     1,  // Index entry
			     CAM_TKIP,
			     1,  // Set Group Key
			     pGlInfo->GTK);
		break;

	case RT_ENC_ALG_AESCCMP:
		AP_Setkey(  Adapter , 
			     	CAM_CONST_BROAD,
			     	1,  // Index entry
			     	CAM_AES,
			     	1,  // Set Group Key
			     	pGlInfo->GTK);
		break;

	case RT_ENC_ALG_WEP40: 
	case RT_ENC_ALG_WEP104:
		{
			static u1Byte	CAM_CONST_ADDR[4][6] = {
				{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
				{0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
				{0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
				{0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
				u1Byte EncAlgo = ((pSecInfo->PairwiseEncAlgorithm == RT_ENC_ALG_WEP40) ? CAM_WEP40 : CAM_WEP104);
	
			for(i = 0; i < 4; i++)
			{
				if(pSecInfo->KeyLen[i] > 0)
				{
					AP_Setkey(
						Adapter , 
						CAM_CONST_ADDR[i],
						i,  // Index entry
						EncAlgo,
						1,
						pSecInfo->KeyBuf[i]);
				}
			}
		}
		break;

	default:
		break;
	}
	}
	
	RT_TRACE( COMP_AUTHENTICATOR, DBG_LOUD, ("<=== Authenticator_GlobalReset()\n") );
	
}
//
// Description:
//	Construct the ARP response packet to support ARP offload.
//
static void ConstructARPResponse(
	PADAPTER padapter,
	u8			*pframe,
	u32			*pLength,
	u8			*pIPAddress
	)
{
	struct rtw_ieee80211_hdr	*pwlanhdr;
	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
	struct wlan_network		*cur_network = &pmlmepriv->cur_network;
	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
	struct security_priv 	*psecuritypriv = &padapter->securitypriv;
	static u8				ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};

	u16		*fctrl;
	u32		pktlen;
	u8		*pARPRspPkt = pframe;
	//for TKIP Cal MIC
	u8		*payload = pframe;
	u8		EncryptionHeadOverhead = 0;

	pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;

	fctrl = &pwlanhdr->frame_ctl;
	*(fctrl) = 0;

	//-------------------------------------------------------------------------
	// MAC Header.
	//-------------------------------------------------------------------------
	SetFrameType(fctrl, WIFI_DATA);
	//SetFrameSubType(fctrl, 0);
	SetToDs(fctrl);
	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
	_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);

	SetSeqNum(pwlanhdr, 0);
	SetDuration(pwlanhdr, 0);
	//SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0);
	//SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data);
	//SET_80211_HDR_TO_DS(pARPRspPkt, 1);
	//SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid);
	//SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress);
	//SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid);

	//SET_80211_HDR_DURATION(pARPRspPkt, 0);
	//SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0);
#ifdef CONFIG_WAPI_SUPPORT
	*pLength = sMacHdrLng;
#else
	*pLength = 24;
#endif


//YJ,del,120503
#if 0
	//-------------------------------------------------------------------------
	// Qos Header: leave space for it if necessary.
	//-------------------------------------------------------------------------
	if(pStaQos->CurrentQosMode > QOS_DISABLE)
	{
		SET_80211_HDR_QOS_EN(pARPRspPkt, 1);
		PlatformZeroMemory(&(Buffer[*pLength]), sQoSCtlLng);
		*pLength += sQoSCtlLng;
	}
#endif
	//-------------------------------------------------------------------------
	// Security Header: leave space for it if necessary.
	//-------------------------------------------------------------------------

	switch (psecuritypriv->dot11PrivacyAlgrthm)
	{
		case _WEP40_:
		case _WEP104_:
			EncryptionHeadOverhead = 4;
			break;
		case _TKIP_:
			EncryptionHeadOverhead = 8;
			break;
		case _AES_:
			EncryptionHeadOverhead = 8;
			break;
#ifdef CONFIG_WAPI_SUPPORT
		case _SMS4_:
			EncryptionHeadOverhead = 18;
			break;
#endif
		default:
			EncryptionHeadOverhead = 0;
	}

	if(EncryptionHeadOverhead > 0)
	{
		_rtw_memset(&(pframe[*pLength]), 0,EncryptionHeadOverhead);
		*pLength += EncryptionHeadOverhead;
		//SET_80211_HDR_WEP(pARPRspPkt, 1);  //Suggested by CCW.
		SetPrivacy(fctrl);
	}

	//-------------------------------------------------------------------------
	// Frame Body.
	//-------------------------------------------------------------------------
	pARPRspPkt =  (u8*)(pframe+ *pLength);
	// LLC header
	_rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
	*pLength += 8;

	// ARP element
	pARPRspPkt += 8;
	SET_ARP_PKT_HW(pARPRspPkt, 0x0100);
	SET_ARP_PKT_PROTOCOL(pARPRspPkt, 0x0008);	// IP protocol
	SET_ARP_PKT_HW_ADDR_LEN(pARPRspPkt, 6);
	SET_ARP_PKT_PROTOCOL_ADDR_LEN(pARPRspPkt, 4);
	SET_ARP_PKT_OPERATION(pARPRspPkt, 0x0200); // ARP response
	SET_ARP_PKT_SENDER_MAC_ADDR(pARPRspPkt, myid(&(padapter->eeprompriv)));
	SET_ARP_PKT_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
	#ifdef CONFIG_ARP_KEEP_ALIVE
	if (rtw_gw_addr_query(padapter)==0) {
		SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
		SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
	}
	else
#endif
	{
		SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, get_my_bssid(&(pmlmeinfo->network)));
		SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pIPAddress);
		DBG_871X("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__, MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
		DBG_871X("%s Target IP Addr" IP_FMT "\n", __FUNCTION__, IP_ARG(pIPAddress));
	}
	*pLength += 28;
	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_)
	{
		u8	mic[8];
		struct mic_data	micdata;
		struct sta_info	*psta = NULL;
		u8	priority[4]={0x0,0x0,0x0,0x0};
		u8	null_key[16]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};

		DBG_871X("%s(): Add MIC\n",__FUNCTION__);

		psta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(&(pmlmeinfo->network)));
		if (psta != NULL) {
			if(_rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],null_key, 16)==_TRUE){
				DBG_871X("%s(): STA dot11tkiptxmickey==0\n",__FUNCTION__);
			}
			//start to calculate the mic code
			rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
		}

		rtw_secmicappend(&micdata, pwlanhdr->addr3, 6);  //DA

		rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); //SA

		priority[0]=0;
		rtw_secmicappend(&micdata, &priority[0], 4);

		rtw_secmicappend(&micdata, payload, 36); //payload length = 8 + 28

		rtw_secgetmic(&micdata,&(mic[0]));

		pARPRspPkt += 28;
		_rtw_memcpy(pARPRspPkt, &(mic[0]),8);

		*pLength += 8;
	}
}
Exemple #11
0
VOID
WPS_AppendElement(
	IN	PADAPTER			Adapter,
	IN	POCTET_STRING		posFrame,
	IN	BOOLEAN				bCheckFrag,
	IN	WPS_INFO_OPCODE	frameType
	)
{
	PSIMPLE_CONFIG_T	pSimpleConfig = GET_SIMPLE_CONFIG(&(GetDefaultAdapter(Adapter)->MgntInfo));
	OCTET_STRING		SimpleConfigInfo;	

	FunctionIn(COMP_WPS);
	#if 0
	if(bCheckFrag)
	{
		// WPS 2.0 Support IE Fragment	for Testbed function
		if(pSimpleConfig->bFragmentIE && pSimpleConfig->IELen <= MAX_SIMPLE_CONFIG_IE_LEN)
		{
			u1Byte tempBuf[MAX_SIMPLE_CONFIG_IE_LEN];
			pu1Byte currPtr;
			pu1Byte currPtrAftOui;
			RT_TRACE(COMP_WPS,DBG_LOUD,("ConstructProbeRequest: in Fragment IE\n"));
			PlatformZeroMemory(tempBuf, MAX_SIMPLE_CONFIG_IE_LEN);
			//Copy the OUI
			currPtr = pSimpleConfig->IEBuf;
			//Tesplan to copy the first octet in the first fragment
			PlatformMoveMemory(tempBuf, currPtr, SIZE_OUI + SIZE_OUI_TYPE);
			currPtr += (SIZE_OUI + SIZE_OUI_TYPE); 
			currPtrAftOui = &tempBuf[SIZE_OUI + SIZE_OUI_TYPE];

			// the first octet
			PlatformMoveMemory(currPtrAftOui, currPtr, 1);
			currPtr += 1;
			FillOctetString(SimpleConfigInfo,tempBuf,(SIZE_OUI + SIZE_OUI_TYPE +1));
			PacketMakeElement( posFrame, EID_Vendor, SimpleConfigInfo);
						
			// the rest octet			
			PlatformZeroMemory(currPtrAftOui, 1);
			PlatformMoveMemory(currPtrAftOui, currPtr, (pSimpleConfig->IELen-(SIZE_OUI + SIZE_OUI_TYPE)-1) );

			FillOctetString(SimpleConfigInfo,tempBuf,(pSimpleConfig->IELen-1));
			PacketMakeElement( posFrame, EID_Vendor, SimpleConfigInfo);

		}
		else if(pSimpleConfig->IELen > MAX_SIMPLE_CONFIG_IE_LEN)
		{
			u1Byte tempBuf[MAX_SIMPLE_CONFIG_IE_LEN];
			pu1Byte currPtr;
			pu1Byte currPtrAftOui;
			PlatformZeroMemory(tempBuf, MAX_SIMPLE_CONFIG_IE_LEN);
			//Copy the OUI
			currPtr = pSimpleConfig->IEBuf;
			//Tesplan to copy the first octet in the first fragment
			PlatformMoveMemory(tempBuf, currPtr, SIZE_OUI + SIZE_OUI_TYPE);
			currPtr += (SIZE_OUI + SIZE_OUI_TYPE); 
			currPtrAftOui = &tempBuf[SIZE_OUI + SIZE_OUI_TYPE];

			// the first fragment
			PlatformMoveMemory(currPtrAftOui, currPtr, (MAX_SIMPLE_CONFIG_IE_LEN - (SIZE_OUI + SIZE_OUI_TYPE)));
			currPtr += (MAX_SIMPLE_CONFIG_IE_LEN - (SIZE_OUI + SIZE_OUI_TYPE));
			FillOctetString(SimpleConfigInfo,tempBuf,(MAX_SIMPLE_CONFIG_IE_LEN - (SIZE_OUI + SIZE_OUI_TYPE)));
			PacketMakeElement( posFrame, EID_Vendor, SimpleConfigInfo);
						
			// the rest octet			
			PlatformZeroMemory(currPtrAftOui, (MAX_SIMPLE_CONFIG_IE_LEN - (SIZE_OUI + SIZE_OUI_TYPE)));
			PlatformMoveMemory(currPtrAftOui, currPtr, (pSimpleConfig->IELen-MAX_SIMPLE_CONFIG_IE_LEN) );

			FillOctetString(SimpleConfigInfo,tempBuf,(pSimpleConfig->IELen-MAX_SIMPLE_CONFIG_IE_LEN));
			PacketMakeElement( posFrame, EID_Vendor, SimpleConfigInfo);
			
		}
		else
		{
			FillOctetString(SimpleConfigInfo, pSimpleConfig->IEBuf, pSimpleConfig->IELen);
			PacketMakeElement( posFrame, EID_Vendor, SimpleConfigInfo);
		}
	}
	else
	#endif
	{
		if(((pSimpleConfig->WpsIeVersion < SUPPORT_WPS_INFO_VERSION) || (wps_IsWPSIEReady(Adapter) == FALSE)) && pSimpleConfig->IELen > 0)
		{
			FillOctetString(SimpleConfigInfo, pSimpleConfig->IEBuf, pSimpleConfig->IELen);
			PacketMakeElement( posFrame, EID_Vendor, SimpleConfigInfo);
		}
		else if(pSimpleConfig->WpsIeVersion == SUPPORT_WPS_INFO_VERSION)
		{
			switch(frameType)
			{
				case WPS_INFO_ASOCREQ_IE:
				{
					FillOctetString(SimpleConfigInfo, pSimpleConfig->ieAsocReqBuf, pSimpleConfig->ieAsocReqLen);
					if(pSimpleConfig->ieAsocReqLen > 0)
						PacketAppendData(posFrame, SimpleConfigInfo);
				}
				break;

				case WPS_INFO_ASOCRSP_IE:
				{
					FillOctetString(SimpleConfigInfo, pSimpleConfig->ieAsocRspBuf, pSimpleConfig->ieAsocRspLen);
					if(pSimpleConfig->ieAsocRspLen > 0)
						PacketAppendData(posFrame, SimpleConfigInfo);
				}
				break;
				
				case WPS_INFO_PROBEREQ_IE:
				{
					FillOctetString(SimpleConfigInfo, pSimpleConfig->ieProbeReqBuf, pSimpleConfig->ieProbeReqLen);
					if(pSimpleConfig->ieProbeReqLen > 0)
						PacketAppendData(posFrame, SimpleConfigInfo);
				}
				break;

				case WPS_INFO_PROBERSP_IE:
				{
					FillOctetString(SimpleConfigInfo, pSimpleConfig->ieProbeRspBuf, pSimpleConfig->ieProbeRspLen);
					if(pSimpleConfig->ieProbeRspLen > 0)
						PacketAppendData(posFrame, SimpleConfigInfo);
				}
				break;

				default: //for MacOS warning.
					break;

			}
		}
	}
}