VOID ApcliWpaSendEapolStart( IN PRTMP_ADAPTER pAd, IN PUCHAR pBssid, IN PMAC_TABLE_ENTRY pMacEntry, IN PAPCLI_STRUCT pApCliEntry) { IEEE8021X_FRAME Packet; UCHAR Header802_3[14]; DBGPRINT(RT_DEBUG_TRACE, ("-----> ApCliWpaSendEapolStart\n")); NdisZeroMemory(Header802_3,sizeof(UCHAR)*14); MAKE_802_3_HEADER(Header802_3, pBssid, &pApCliEntry->CurrentAddress[0], EAPOL); // Zero message 2 body NdisZeroMemory(&Packet, sizeof(Packet)); Packet.Version = EAPOL_VER; Packet.Type = EAPOLStart; Packet.Length = cpu2be16(0); // Copy frame to Tx ring RTMPToWirelessSta((PRTMP_ADAPTER)pAd, pMacEntry, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, 4, TRUE); DBGPRINT(RT_DEBUG_TRACE, ("<----- WpaSendEapolStart\n")); }
/* ======================================================================== Routine Description: Send EAPoL-Start packet to AP. Arguments: pAd - NIC Adapter pointer Return Value: None IRQL = DISPATCH_LEVEL Note: Actions after link up 1. Change the correct parameters 2. Send EAPOL - START ======================================================================== */ VOID WpaSendEapolStart( IN PRTMP_ADAPTER pAd, IN PUCHAR pBssid) { IEEE8021X_FRAME Packet; UCHAR Header802_3[14]; DBGPRINT(RT_DEBUG_TRACE, ("-----> WpaSendEapolStart\n")); NdisZeroMemory(Header802_3,sizeof(UCHAR)*14); MAKE_802_3_HEADER(Header802_3, pBssid, &pAd->CurrentAddress[0], EAPOL); /* Zero message 2 body */ NdisZeroMemory(&Packet, sizeof(Packet)); Packet.Version = EAPOL_VER; Packet.Type = EAPOLStart; Packet.Length = cpu2be16(0); /* Copy frame to Tx ring */ RTMPToWirelessSta((PRTMP_ADAPTER)pAd, &pAd->MacTab.Content[BSSID_WCID], Header802_3, LENGTH_802_3, (PUCHAR)&Packet, 4, TRUE); DBGPRINT(RT_DEBUG_TRACE, ("<----- WpaSendEapolStart\n")); }
/* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ NDIS_STATUS TDLS_ChannelSwitchRspAction( IN PRTMP_ADAPTER pAd, IN PRT_802_11_TDLS pTDLS, IN USHORT ChSwitchTime, IN USHORT ChSwitchTimeOut, IN UINT16 StatusCode, IN UCHAR FrameType) { UCHAR TDLS_ETHERTYPE[] = {0x89, 0x0d}; UCHAR Header802_3[14]; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0; ULONG TempLen; UCHAR RemoteFrameType = PROTO_NAME_TDLS; NDIS_STATUS NStatus = NDIS_STATUS_SUCCESS; DBGPRINT(RT_DEBUG_WARN, ("TDLS ===> TDLS_ChannelSwitchRspAction\n")); MAKE_802_3_HEADER(Header802_3, pTDLS->MacAddr, pAd->CurrentAddress, TDLS_ETHERTYPE); // Allocate buffer for transmitting message NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_ERROR,("ACT - TDLS_ChannelSwitchRspAction() allocate memory failed \n")); return NStatus; } MakeOutgoingFrame(pOutBuffer, &TempLen, 1, &RemoteFrameType, END_OF_ARGS); FrameLen = FrameLen + TempLen; TDLS_BuildChannelSwitchResponse(pAd, pOutBuffer, &FrameLen, pTDLS, ChSwitchTime, ChSwitchTimeOut, StatusCode); RTMPToWirelessSta(pAd, &pAd->MacTab.Content[pTDLS->MacTabMatchWCID], Header802_3, LENGTH_802_3, pOutBuffer, (UINT)FrameLen, FALSE, FrameType); hex_dump("TDLS send channel switch response pack", pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); DBGPRINT(RT_DEBUG_WARN, ("TDLS <=== TDLS_ChannelSwitchRspAction\n")); return NStatus; }
VOID WpaMicFailureReportFrame( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { PUCHAR pOutBuffer = NULL; UCHAR Header802_3[14]; ULONG FrameLen = 0; EAPOL_PACKET Packet; UCHAR Mic[16]; BOOLEAN bUnicast; DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame ----->\n")); bUnicast = (Elem->Msg[0] == 1 ? TRUE:FALSE); pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER); // init 802.3 header and Fill Packet MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL); NdisZeroMemory(&Packet, sizeof(Packet)); Packet.ProVer = EAPOL_VER; Packet.ProType = EAPOLKey; Packet.KeyDesc.Type = WPA1_KEY_DESC; // Request field presented Packet.KeyDesc.KeyInfo.Request = 1; if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) { Packet.KeyDesc.KeyInfo.KeyDescVer = 2; } else // TKIP { Packet.KeyDesc.KeyInfo.KeyDescVer = 1; } Packet.KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY); // KeyMic field presented Packet.KeyDesc.KeyInfo.KeyMic = 1; // Error field presented Packet.KeyDesc.KeyInfo.Error = 1; // Update packet length after decide Key data payload SET_UINT16_TO_ARRARY(Packet.Body_Len, LEN_EAPOL_KEY_MSG) // Key Replay Count NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY); inc_byte_array(pAd->StaCfg.ReplayCounter, 8); // Convert to little-endian format. *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo)); MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory if(pOutBuffer == NULL) { return; } // Prepare EAPOL frame for MIC calculation // Be careful, only EAPOL frame is counted for MIC calculation MakeOutgoingFrame(pOutBuffer, &FrameLen, CONV_ARRARY_TO_UINT16(Packet.Body_Len) + 4, &Packet, END_OF_ARGS); // Prepare and Fill MIC value NdisZeroMemory(Mic, sizeof(Mic)); if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) { // AES UCHAR digest[20] = {0}; HMAC_SHA1(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE); NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC); } else { // TKIP HMAC_MD5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic, MD5_DIGEST_SIZE); } NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC); // copy frame to Tx ring and send MIC failure report frame to authenticator RTMPToWirelessSta(pAd, &pAd->MacTab.Content[BSSID_WCID], Header802_3, LENGTH_802_3, (PUCHAR)&Packet, CONV_ARRARY_TO_UINT16(Packet.Body_Len) + 4, FALSE); MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer); DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame <-----\n")); }
VOID WpaMicFailureReportFrame( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { PUCHAR pOutBuffer = NULL; UCHAR Header802_3[14]; ULONG FrameLen = 0; UCHAR *mpool; PEAPOL_PACKET pPacket; UCHAR Mic[16]; BOOLEAN bUnicast; DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame ----->\n")); bUnicast = (Elem->Msg[0] == 1 ? TRUE:FALSE); pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER); /* init 802.3 header and Fill Packet */ MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL); /* Allocate memory for output */ os_alloc_mem(NULL, (PUCHAR *)&mpool, TX_EAPOL_BUFFER); if (mpool == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("!!!%s : no memory!!!\n", __FUNCTION__)); return; } pPacket = (PEAPOL_PACKET)mpool; NdisZeroMemory(pPacket, TX_EAPOL_BUFFER); pPacket->ProVer = EAPOL_VER; pPacket->ProType = EAPOLKey; pPacket->KeyDesc.Type = WPA1_KEY_DESC; /* Request field presented */ pPacket->KeyDesc.KeyInfo.Request = 1; if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) { pPacket->KeyDesc.KeyInfo.KeyDescVer = 2; } else /* TKIP */ { pPacket->KeyDesc.KeyInfo.KeyDescVer = 1; } pPacket->KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY); /* KeyMic field presented */ pPacket->KeyDesc.KeyInfo.KeyMic = 1; /* Error field presented */ pPacket->KeyDesc.KeyInfo.Error = 1; /* Update packet length after decide Key data payload */ SET_UINT16_TO_ARRARY(pPacket->Body_Len, MIN_LEN_OF_EAPOL_KEY_MSG) /* Key Replay Count */ NdisMoveMemory(pPacket->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY); inc_byte_array(pAd->StaCfg.ReplayCounter, 8); /* Convert to little-endian format. */ *((USHORT *)&pPacket->KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&pPacket->KeyDesc.KeyInfo)); MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); /* allocate memory */ if(pOutBuffer == NULL) { os_free_mem(NULL, mpool); return; } /* Prepare EAPOL frame for MIC calculation Be careful, only EAPOL frame is counted for MIC calculation */ MakeOutgoingFrame(pOutBuffer, &FrameLen, CONV_ARRARY_TO_UINT16(pPacket->Body_Len) + 4, pPacket, END_OF_ARGS); /* Prepare and Fill MIC value */ NdisZeroMemory(Mic, sizeof(Mic)); if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) { /* AES */ UCHAR digest[20] = {0}; RT_HMAC_SHA1(pAd->StaCfg.PTK, LEN_PTK_KCK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE); NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC); } else { /* TKIP */ RT_HMAC_MD5(pAd->StaCfg.PTK, LEN_PTK_KCK, pOutBuffer, FrameLen, Mic, MD5_DIGEST_SIZE); } NdisMoveMemory(pPacket->KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC); /* copy frame to Tx ring and send MIC failure report frame to authenticator */ RTMPToWirelessSta(pAd, &pAd->MacTab.Content[BSSID_WCID], Header802_3, LENGTH_802_3, (PUCHAR)pPacket, CONV_ARRARY_TO_UINT16(pPacket->Body_Len) + 4, FALSE); MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer); os_free_mem(NULL, mpool); DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame <-----\n")); }
/* ======================================================================== Routine Description: Send a traffic response frame. Arguments: pAd - WLAN control block pointer pTDLS - the peer entry Return Value: NDIS_STATUS_SUCCESS NDIS_STATUS_FAILURE Note: ======================================================================== */ static NDIS_STATUS TDLS_UAPSD_TrafficRspSend( IN PRTMP_ADAPTER pAd, IN UCHAR *pPeerMac, IN UCHAR PeerToken) { MAC_TABLE_ENTRY *pMacEntry; RT_802_11_TDLS *pTDLS = NULL; UCHAR TDLS_ETHERTYPE[] = {0x89, 0x0d}; UCHAR Header802_3[14]; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0; ULONG TempLen; INT32 LinkId; UCHAR RemoteFrameType = PROTO_NAME_TDLS; NDIS_STATUS NStatus = NDIS_STATUS_FAILURE; DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__)); /* search TDLS entry */ LinkId = TDLS_SearchLinkId(pAd, pPeerMac); if (TDLS_UAPSD_IS_LINK_INVALID(LinkId)) { DBGPRINT(RT_DEBUG_TRACE, ("%s: can not find the LinkId!\n", __FUNCTION__)); TDLS_UAPSD_REBUILD_LINK(pAd, pPeerMac); goto LabelExit; } DBGPRINT(RT_DEBUG_TRACE, ("tdls uapsd> LinkId = %d\n", LinkId)); pTDLS = TDLS_UAPSD_ENTRY_GET(pAd, LinkId); /* sanity check */ if (TDLS_UAPSD_IS_CONN_NOT_BUILT(pTDLS)) { DBGPRINT(RT_DEBUG_TRACE, ("tdls uapsd> link is not yet built " "so we can not send a traffic ind to the peer!!!")); goto LabelExit; } /* init */ MAKE_802_3_HEADER(Header802_3, pTDLS->MacAddr, pAd->CurrentAddress, TDLS_ETHERTYPE); /* allocate buffer for transmitting message */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) goto LabelExit; /* build the frame */ MakeOutgoingFrame(pOutBuffer, &TempLen, 1, &RemoteFrameType, END_OF_ARGS); FrameLen = FrameLen + TempLen; TDLS_UAPSD_TrafficRspBuild(pAd, pOutBuffer, &FrameLen, pTDLS, PeerToken); hex_dump("TDLS UAPSD Peer Traffic Response sending packet", pOutBuffer, FrameLen); /* need to set the power save mode of the peer to ACTIVE */ /* we will recover its mode after EOSP frame is received */ pMacEntry = MacTableLookup(pAd, pTDLS->MacAddr); if (pMacEntry == NULL) goto LabelExit; /* peer can not sleep for a while */ RTMP_PS_VIRTUAL_WAKEUP_PEER(pMacEntry); /* send the frame to the peer without AP's help */ TDLS_UAPSD_PKT_SEND_TO_PEER(pAd, Header802_3, pOutBuffer, FrameLen, pTDLS); /* hex_dump("TDLS traffic response send pack", pOutBuffer, FrameLen); */ NStatus = NDIS_STATUS_SUCCESS; /* free resources */ LabelExit: if (pOutBuffer != NULL) MlmeFreeMemory(pAd, pOutBuffer); return NStatus; }
/* ======================================================================== Routine Description: Build the traffic indication frame. Arguments: pAd - WLAN control block pointer pPeerMac - the peer pFrameBuf - frame pHeader802_3 - frame header Return Value: Frame Length Note: ======================================================================== */ static ULONG TDLS_UAPSD_TrafficIndBuild( IN PRTMP_ADAPTER pAd, IN UCHAR *pPeerMac, OUT UCHAR *pFrameBuf, OUT UCHAR *pHeader802_3) { RT_802_11_TDLS *pTDLS = NULL; UCHAR TDLS_ETHERTYPE[] = {0x89, 0x0d}; ULONG FrameLen = 0; INT32 LinkId; BOOLEAN TimerCancelled; DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__)); /* search TDLS entry */ LinkId = TDLS_SearchLinkId(pAd, pPeerMac); if (TDLS_UAPSD_IS_LINK_INVALID(LinkId)) { DBGPRINT(RT_DEBUG_TRACE, ("%s: can not find the LinkId!\n", __FUNCTION__)); TDLS_UAPSD_REBUILD_LINK(pAd, pPeerMac); goto LabelExit; } DBGPRINT(RT_DEBUG_TRACE, ("tdls uapsd> LinkId = %d\n", LinkId)); pTDLS = TDLS_UAPSD_ENTRY_GET(pAd, LinkId); /* sanity check */ if (TDLS_UAPSD_IS_CONN_NOT_BUILT(pTDLS)) { DBGPRINT(RT_DEBUG_TRACE, ("tdls uapsd> link is not yet built " "so we can not send a traffic ind to the peer!!!")); goto LabelExit; } if (pTDLS->FlgIsWaitingUapsdTraRsp == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("tdls uapsd> traffic ind was sent before!\n")); goto LabelExit; /* has sent it */ } pTDLS->FlgIsWaitingUapsdTraRsp = TRUE; /* init packet header */ MAKE_802_3_HEADER(pHeader802_3, pTDLS->MacAddr, pAd->CurrentAddress, TDLS_ETHERTYPE); /* build the frame */ TDLS_UAPSD_TrafficIndPayloadBuild(pAd, pFrameBuf, &FrameLen, pTDLS); hex_dump("TDLS UAPSD Peer Traffic Ind sending packet", pFrameBuf, FrameLen); /* 11.2.1.14.1 Peer U-APSD Behavior at the PU buffer STA When no corresponding TDLS Peer Traffic Response frame has been received within dot11TDLSResponseTimeout after sending a TDLS Peer Traffic Indication frame, the STA shall tear down the direct link. The default value is 5 seconds. */ /* set traffic indication timer */ RTMPCancelTimer(&pTDLS->Timer, &TimerCancelled); RTMPSetTimer(&pTDLS->Timer, TDLS_TIMEOUT); /* free resources */ LabelExit: return FrameLen; }
/* ======================================================================== Routine Description: Simulate to send a TDLS Setup request to a peer. Arguments: pAd - WLAN control block pointer Argc - the number of input parameters *pArgv - input parameters Return Value: None Note: 1. Command Format: iwpriv ra0 set tdls=51_[PEER MAC] 11.21.4 TDLS direct-link establishment TDLS Setup Request frames, TDLS Setup Response frames, and TDLS Setup Confirm frames shall be transmitted through the AP and shall not be transmitted to a group address. ======================================================================== */ static VOID TDLS_UAPSD_CmdSimSetupReqSend( IN PRTMP_ADAPTER pAd, IN INT32 Argc, IN CHAR *pArgv) { MLME_QUEUE_ELEM *pElem; RT_802_11_TDLS TDLS, *pTDLS = &TDLS; UCHAR TDLS_ETHERTYPE[] = {0x89, 0x0d}; UCHAR Header802_3[14]; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0; ULONG TempLen; UCHAR RemoteFrameType = PROTO_NAME_TDLS; NDIS_STATUS NStatus = NDIS_STATUS_SUCCESS; UCHAR PeerMac[6]; UINT32 IdTdls; /* get MAC address */ TDLS_UAPSD_CmdUtilMacGet(&pArgv, PeerMac); /* allocate buffer for transmitting message */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) return; os_alloc_mem(NULL, (UCHAR **)&pElem, sizeof(MLME_QUEUE_ELEM)); if (pElem == NULL) { MlmeFreeMemory(pAd, pOutBuffer); return; } /* init link entry */ NdisZeroMemory(pTDLS, sizeof(RT_802_11_TDLS)); pTDLS->TimeOut = 0; COPY_MAC_ADDR(pTDLS->MacAddr, PeerMac); pTDLS->Valid = 1; /* search a empty entry */ for(IdTdls=0; IdTdls<MAX_NUM_OF_TDLS_ENTRY; IdTdls++) { if (!pAd->StaCfg.TdlsInfo.TDLSEntry[IdTdls].Valid) { NdisMoveMemory(&pAd->StaCfg.TdlsInfo.TDLSEntry[IdTdls], pTDLS, sizeof(RT_802_11_TDLS_UI)); break; } } if (IdTdls == MAX_NUM_OF_TDLS_ENTRY) { MlmeFreeMemory(pAd, pOutBuffer); os_free_mem(NULL, pElem); return; } /* init request frame */ MAKE_802_3_HEADER(Header802_3, pTDLS->MacAddr, pAd->CurrentAddress, TDLS_ETHERTYPE); MakeOutgoingFrame(pOutBuffer, &TempLen, 1, &RemoteFrameType, END_OF_ARGS); FrameLen = FrameLen + TempLen; TDLS_BuildSetupRequest(pAd, pOutBuffer, &FrameLen, TDLS_UAPSD_ENTRY_GET(pAd, IdTdls)); hex_dump("Request=", pOutBuffer, FrameLen); TDLS_UAPSD_PKT_SEND_THROUGH_AP(pAd, Header802_3, pOutBuffer, FrameLen); /* init response frame */ FrameLen += LENGTH_802_11 + LENGTH_802_1_H; pElem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + FrameLen; /* copy payload type, category, action (3B) */ memcpy(pElem->Msg + LENGTH_802_11 + LENGTH_802_1_H, pOutBuffer, 3); /* status code = 0x00 00 (2B) */ *(USHORT *)(pElem->Msg + LENGTH_802_11 + LENGTH_802_1_H + 3) = 0x00; /* copy others */ memcpy(pElem->Msg + LENGTH_802_11 + LENGTH_802_1_H + 3 + 2, pOutBuffer + 3, FrameLen - 3); /* handle response frame */ TDLS_PeerSetupRspAction(pAd, pElem); /* free memory */ MlmeFreeMemory(pAd, pOutBuffer); os_free_mem(NULL, pElem); } /* End of TDLS_UAPSD_CmdSimSetupReqSend */
VOID RTMPHandleSTAKey( IN PRTMP_ADAPTER pAd, IN PMAC_TABLE_ENTRY pEntry, IN MLME_QUEUE_ELEM *Elem) { extern UCHAR OUI_WPA2_WEP40[]; ULONG FrameLen = 0; PUCHAR pOutBuffer = NULL; UCHAR Header802_3[14]; UCHAR *mpool; PEAPOL_PACKET pOutPacket; PEAPOL_PACKET pSTAKey; PHEADER_802_11 pHeader; UCHAR Offset = 0; ULONG MICMsgLen; UCHAR DA[MAC_ADDR_LEN]; UCHAR Key_Data[512]; UCHAR key_length; UCHAR mic[LEN_KEY_DESC_MIC]; UCHAR rcv_mic[LEN_KEY_DESC_MIC]; UCHAR digest[80]; UCHAR temp[64]; PMAC_TABLE_ENTRY pDaEntry; /*Benson add for big-endian 20081016--> */ KEY_INFO peerKeyInfo; /*Benson add 20081016 <-- */ DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleSTAKey\n")); if (!pEntry) return; if ((pEntry->WpaState != AS_PTKINITDONE)) { DBGPRINT(RT_DEBUG_ERROR, ("Not expect calling STAKey hand shaking here")); return; } pHeader = (PHEADER_802_11) Elem->Msg; /* QoS control field (2B) is took off */ /* if (pHeader->FC.SubType & 0x08) */ /* Offset += 2; */ pSTAKey = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H + Offset]; /*Benson add for big-endian 20081016--> */ NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo)); NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pSTAKey->KeyDesc.KeyInfo, sizeof(KEY_INFO)); *((USHORT *)&peerKeyInfo) = cpu2le16(*((USHORT *)&peerKeyInfo)); /*Benson add 20081016 <-- */ /* Check Replay Counter */ if (!RTMPEqualMemory(pSTAKey->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY)) { DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in STAKey handshake!! \n")); DBGPRINT(RT_DEBUG_ERROR, ("Receive : %d %d %d %d \n", pSTAKey->KeyDesc.ReplayCounter[0], pSTAKey->KeyDesc.ReplayCounter[1], pSTAKey->KeyDesc.ReplayCounter[2], pSTAKey->KeyDesc.ReplayCounter[3])); DBGPRINT(RT_DEBUG_ERROR, ("Current : %d %d %d %d \n", pEntry->R_Counter[4],pEntry->R_Counter[5], pEntry->R_Counter[6],pEntry->R_Counter[7])); return; } /* Check MIC, if not valid, discard silently */ NdisMoveMemory(DA, &pSTAKey->KeyDesc.KeyData[6], MAC_ADDR_LEN); if (peerKeyInfo.KeyMic && peerKeyInfo.Secure && peerKeyInfo.Request)/*Benson add for big-endian 20081016 --> */ { pEntry->bDlsInit = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("STAKey Initiator: %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pEntry->Addr))); } MICMsgLen = pSTAKey->Body_Len[1] | ((pSTAKey->Body_Len[0]<<8) && 0xff00); MICMsgLen += LENGTH_EAPOL_H; if (MICMsgLen > (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H)) { DBGPRINT(RT_DEBUG_ERROR, ("Receive wrong format EAPOL packets \n")); return; } /* This is proprietary DLS protocol, it will be adhered when spec. is finished. */ NdisZeroMemory(temp, 64); NdisZeroMemory(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, sizeof(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK)); NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32); WpaDerivePTK(pAd, temp, temp, pAd->ApCfg.MBSSID[pEntry->apidx].wdev.bssid, temp, pEntry->Addr, pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK); DBGPRINT(RT_DEBUG_TRACE, ("PTK-%x %x %x %x %x %x %x %x \n", pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[0], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[1], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[2], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[3], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[4], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[5], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[6], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[7])); /* Record the received MIC for check later */ NdisMoveMemory(rcv_mic, pSTAKey->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); NdisZeroMemory(pSTAKey->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); if (pEntry->WepStatus == Ndis802_11TKIPEnable) { RT_HMAC_MD5(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, (PUCHAR)pSTAKey, MICMsgLen, mic, MD5_DIGEST_SIZE); } else { RT_HMAC_SHA1(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, (PUCHAR)pSTAKey, MICMsgLen, digest, SHA1_DIGEST_SIZE); NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC); } if (!RTMPEqualMemory(rcv_mic, mic, LEN_KEY_DESC_MIC)) { DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in STAKey handshake!! \n")); return; } else DBGPRINT(RT_DEBUG_TRACE, ("MIC VALID in STAKey handshake!! \n")); /* Receive init STA's STAKey Message-2, and terminate the handshake */ /*if (pEntry->bDlsInit && !pSTAKey->KeyDesc.KeyInfo.Request) */ if (pEntry->bDlsInit && !peerKeyInfo.Request) /*Benson add for big-endian 20081016 --> */ { pEntry->bDlsInit = FALSE; DBGPRINT(RT_DEBUG_TRACE, ("Receive init STA's STAKey Message-2, STAKey handshake finished \n")); return; } /* Receive init STA's STAKey Message-2, and terminate the handshake */ if (RTMPEqualMemory(&pSTAKey->KeyDesc.KeyData[2], OUI_WPA2_WEP40, 3)) { DBGPRINT(RT_DEBUG_WARN, ("Receive a STAKey message which not support currently, just drop it \n")); return; } do { pDaEntry = MacTableLookup(pAd, DA); if (!pDaEntry) break; if ((pDaEntry->WpaState != AS_PTKINITDONE)) { DBGPRINT(RT_DEBUG_ERROR, ("Not expect calling STAKey hand shaking here \n")); break; } MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); /* allocate memory */ if(pOutBuffer == NULL) break; MAKE_802_3_HEADER(Header802_3, pDaEntry->Addr, pAd->ApCfg.MBSSID[pDaEntry->apidx].wdev.bssid, EAPOL); /* Increment replay counter by 1 */ ADD_ONE_To_64BIT_VAR(pDaEntry->R_Counter); /* Allocate memory for output */ os_alloc_mem(NULL, (PUCHAR *)&mpool, TX_EAPOL_BUFFER); if (mpool == NULL) { MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer); DBGPRINT(RT_DEBUG_ERROR, ("!!!%s : no memory!!!\n", __FUNCTION__)); return; } pOutPacket = (PEAPOL_PACKET)mpool; NdisZeroMemory(pOutPacket, TX_EAPOL_BUFFER); /* 0. init Packet and Fill header */ pOutPacket->ProVer = EAPOL_VER; pOutPacket->ProType = EAPOLKey; pOutPacket->Body_Len[1] = 0x5f; /* 1. Fill replay counter */ /* NdisMoveMemory(pDaEntry->R_Counter, pAd->ApCfg.R_Counter, sizeof(pDaEntry->R_Counter)); */ NdisMoveMemory(pOutPacket->KeyDesc.ReplayCounter, pDaEntry->R_Counter, LEN_KEY_DESC_REPLAY); /* 2. Fill key version, keyinfo, key len */ pOutPacket->KeyDesc.KeyInfo.KeyDescVer= GROUP_KEY; pOutPacket->KeyDesc.KeyInfo.KeyType = GROUPKEY; pOutPacket->KeyDesc.KeyInfo.Install = 1; pOutPacket->KeyDesc.KeyInfo.KeyAck = 1; pOutPacket->KeyDesc.KeyInfo.KeyMic = 1; pOutPacket->KeyDesc.KeyInfo.Secure = 1; pOutPacket->KeyDesc.KeyInfo.EKD_DL = 1; DBGPRINT(RT_DEBUG_TRACE, ("STAKey handshake for peer STA %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(DA))); if ((pDaEntry->AuthMode == Ndis802_11AuthModeWPA) || (pDaEntry->AuthMode == Ndis802_11AuthModeWPAPSK)) { pOutPacket->KeyDesc.Type = WPA1_KEY_DESC; DBGPRINT(RT_DEBUG_TRACE, ("pDaEntry->AuthMode == Ndis802_11AuthModeWPA/WPAPSK\n")); } else if ((pDaEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pDaEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) { pOutPacket->KeyDesc.Type = WPA2_KEY_DESC; pOutPacket->KeyDesc.KeyDataLen[1] = 0; DBGPRINT(RT_DEBUG_TRACE, ("pDaEntry->AuthMode == Ndis802_11AuthModeWPA2/WPA2PSK\n")); } pOutPacket->KeyDesc.KeyLength[1] = LEN_TKIP_TK; pOutPacket->KeyDesc.KeyDataLen[1] = LEN_TKIP_TK; pOutPacket->KeyDesc.KeyInfo.KeyDescVer = KEY_DESC_TKIP; if (pDaEntry->WepStatus == Ndis802_11AESEnable) { pOutPacket->KeyDesc.KeyLength[1] = LEN_AES_TK; pOutPacket->KeyDesc.KeyDataLen[1] = LEN_AES_TK; pOutPacket->KeyDesc.KeyInfo.KeyDescVer = KEY_DESC_AES; } /* Key Data Encapsulation format, use Ralink OUI to distinguish proprietary and standard. */ Key_Data[0] = 0xDD; Key_Data[1] = 0x00; /* Length (This field will be filled later) */ Key_Data[2] = 0x00; /* OUI */ Key_Data[3] = 0x0C; /* OUI */ Key_Data[4] = 0x43; /* OUI */ Key_Data[5] = 0x02; /* Data Type (STAKey Key Data Encryption) */ /* STAKey Data Encapsulation format */ Key_Data[6] = 0x00; /*Reserved */ Key_Data[7] = 0x00; /*Reserved */ /* STAKey MAC address */ NdisMoveMemory(&Key_Data[8], pEntry->Addr, MAC_ADDR_LEN); /* initiator MAC address */ /* STAKey (Handle the difference between TKIP and AES-CCMP) */ if (pDaEntry->WepStatus == Ndis802_11AESEnable) { Key_Data[1] = 0x1E; /* 4+2+6+16(OUI+Reserved+STAKey_MAC_Addr+STAKey) */ NdisMoveMemory(&Key_Data[14], pEntry->PairwiseKey.Key, LEN_AES_TK); } else { Key_Data[1] = 0x2E; /* 4+2+6+32(OUI+Reserved+STAKey_MAC_Addr+STAKey) */ NdisMoveMemory(&Key_Data[14], pEntry->PairwiseKey.Key, LEN_TK); NdisMoveMemory(&Key_Data[14+LEN_TK], pEntry->PairwiseKey.TxMic, LEN_TKIP_MIC); NdisMoveMemory(&Key_Data[14+LEN_TK+LEN_TKIP_MIC], pEntry->PairwiseKey.RxMic, LEN_TKIP_MIC); } key_length = Key_Data[1]; pOutPacket->Body_Len[1] = key_length + 0x5f; /* This is proprietary DLS protocol, it will be adhered when spec. is finished. */ NdisZeroMemory(temp, 64); NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32); WpaDerivePTK(pAd, temp, temp, pAd->ApCfg.MBSSID[pEntry->apidx].wdev.bssid, temp, DA, pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK); DBGPRINT(RT_DEBUG_TRACE, ("PTK-0-%x %x %x %x %x %x %x %x \n", pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[0], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[1], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[2], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[3], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[4], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[5], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[6], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[7])); NdisMoveMemory(pOutPacket->KeyDesc.KeyData, Key_Data, key_length); NdisZeroMemory(mic, sizeof(mic)); *(USHORT *)(&pOutPacket->KeyDesc.KeyInfo) = cpu2le16(*(USHORT *)(&pOutPacket->KeyDesc.KeyInfo)); MakeOutgoingFrame(pOutBuffer, &FrameLen, pOutPacket->Body_Len[1] + 4, pOutPacket, END_OF_ARGS); /* Calculate MIC */ if (pDaEntry->WepStatus == Ndis802_11AESEnable) { RT_HMAC_SHA1(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE); NdisMoveMemory(pOutPacket->KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC); } else { RT_HMAC_MD5(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, pOutBuffer, FrameLen, mic, MD5_DIGEST_SIZE); NdisMoveMemory(pOutPacket->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC); } RTMPToWirelessSta(pAd, pDaEntry, Header802_3, LENGTH_802_3, (PUCHAR)pOutPacket, pOutPacket->Body_Len[1] + 4, FALSE); MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer); os_free_mem(NULL, mpool); }while(FALSE); DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleSTAKey: FrameLen=%ld\n", FrameLen)); }
/* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ NDIS_STATUS TDLS_ChannelSwitchReqAction( IN PRTMP_ADAPTER pAd, IN PMLME_TDLS_CH_SWITCH_STRUCT pChSwitchReq) { UCHAR TDLS_ETHERTYPE[] = {0x89, 0x0d}; UCHAR Header802_3[14]; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0; ULONG TempLen; UCHAR RemoteFrameType = PROTO_NAME_TDLS; NDIS_STATUS NStatus = NDIS_STATUS_SUCCESS; MAC_TABLE_ENTRY *pEntry = NULL; UINT16 SwitchTime = pAd->StaCfg.TdlsInfo.TdlsSwitchTime; //micro seconds UINT16 SwitchTimeout = pAd->StaCfg.TdlsInfo.TdlsSwitchTimeout; // micro seconds int LinkId = 0xff; PRT_802_11_TDLS pTDLS = NULL; DBGPRINT(RT_DEBUG_WARN, ("====> TDLS_ChannelSwitchReqAction\n")); MAKE_802_3_HEADER(Header802_3, pChSwitchReq->PeerMacAddr, pAd->CurrentAddress, TDLS_ETHERTYPE); // Allocate buffer for transmitting message NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) return NStatus; MakeOutgoingFrame(pOutBuffer, &TempLen, 1, &RemoteFrameType, END_OF_ARGS); FrameLen = FrameLen + TempLen; TDLS_BuildChannelSwitchRequest(pAd, pOutBuffer, &FrameLen, pChSwitchReq->PeerMacAddr,SwitchTime, SwitchTimeout, pChSwitchReq->TargetChannel, pChSwitchReq->TargetChannelBW); pEntry = MacTableLookup(pAd, pChSwitchReq->PeerMacAddr); if (pEntry && IS_ENTRY_TDLS(pEntry)) { pTDLS->ChannelSwitchCurrentState = TDLS_CHANNEL_SWITCH_WAIT_RSP; if (pChSwitchReq->TargetChannel != pAd->CommonCfg.Channel) RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3, pOutBuffer, (UINT)FrameLen, FALSE, RTMP_TDLS_SPECIFIC_EDCA); else RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3, pOutBuffer, (UINT)FrameLen, FALSE, RTMP_TDLS_SPECIFIC_HCCA); pAd->StaCfg.TdlsCurrentChannel = pChSwitchReq->TargetChannel; pAd->StaCfg.TdlsCurrentChannelBW = pChSwitchReq->TargetChannelBW; } else { DBGPRINT(RT_DEBUG_ERROR, ("Can't find TDLS entry on mac TABLE !!!!\n")); } hex_dump("TDLS switch channel request send pack", pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); DBGPRINT(RT_DEBUG_WARN, ("<==== TDLS_ChannelSwitchReqAction\n")); return NStatus; }