/* ========================================================================== Description: IRQL = DISPATCH_LEVEL ========================================================================== */ VOID PeerAuthRspAtSeq2Action( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM * Elem) { UCHAR Addr2[MAC_ADDR_LEN]; USHORT Seq, Status, RemoteStatus, Alg; UCHAR iv_hdr[4]; /* UCHAR ChlgText[CIPHER_TEXT_LEN]; */ UCHAR *ChlgText = NULL; /* UCHAR CyperChlgText[CIPHER_TEXT_LEN + 8 + 8]; */ UCHAR *CyperChlgText = NULL; ULONG c_len = 0; HEADER_802_11 AuthHdr; BOOLEAN TimerCancelled; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; USHORT Status2; UCHAR ChallengeIe = IE_CHALLENGE_TEXT; UCHAR len_challengeText = CIPHER_TEXT_LEN; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **) & ChlgText, CIPHER_TEXT_LEN); if (ChlgText == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: ChlgText Allocate memory fail!!!\n", __FUNCTION__)); return; } os_alloc_mem(NULL, (UCHAR **) & CyperChlgText, CIPHER_TEXT_LEN + 8 + 8); if (CyperChlgText == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: CyperChlgText Allocate memory fail!!!\n", __FUNCTION__)); os_free_mem(NULL, ChlgText); return; } if (PeerAuthSanity (pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, (PCHAR) ChlgText)) { if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 2) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Receive AUTH_RSP seq#2 to me (Alg=%d, Status=%d)\n", Alg, Status)); RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled); if (Status == MLME_SUCCESS) { /* Authentication Mode "LEAP" has allow for CCX 1.X */ if (pAd->MlmeAux.Alg == Ndis802_11AuthModeOpen) { pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status, 0); } else { /* 2. shared key, need to be challenged */ Seq++; RemoteStatus = MLME_SUCCESS; /* Get an unused nonpaged memory */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthRspAtSeq2Action() allocate memory fail\n")); pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; Status2 = MLME_FAIL_NO_RESOURCE; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status2, 0); goto LabelOK; } DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH request seq#3...\n")); MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr2, #ifdef P2P_SUPPORT pAd->CurrentAddress, #endif /* P2P_SUPPORT */ pAd->MlmeAux.Bssid); AuthHdr.FC.Wep = 1; /* TSC increment */ INC_TX_TSC(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxTsc, LEN_WEP_TSC); /* Construct the 4-bytes WEP IV header */ RTMPConstructWEPIVHdr(pAd->StaCfg.DefaultKeyId, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxTsc, iv_hdr); Alg = cpu2le16(*(USHORT *) & Alg); Seq = cpu2le16(*(USHORT *) & Seq); RemoteStatus = cpu2le16(*(USHORT *) &RemoteStatus); /* Construct message text */ MakeOutgoingFrame(CyperChlgText, &c_len, 2, &Alg, 2, &Seq, 2, &RemoteStatus, 1, &ChallengeIe, 1, &len_challengeText, len_challengeText, ChlgText, END_OF_ARGS); if (RTMPSoftEncryptWEP(pAd, iv_hdr, &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], CyperChlgText, c_len) == FALSE) { MlmeFreeMemory(pAd, pOutBuffer); pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; Status2 = MLME_FAIL_NO_RESOURCE; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status2, 0); goto LabelOK; } /* Update the total length for 4-bytes ICV */ c_len += LEN_ICV; MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof (HEADER_802_11), &AuthHdr, LEN_WEP_IV_HDR, iv_hdr, c_len, CyperChlgText, END_OF_ARGS); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); RTMPSetTimer(&pAd->MlmeAux.AuthTimer, AUTH_TIMEOUT); pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ4; } } else { pAd->StaCfg.AuthFailReason = Status; COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2); pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status, 0); } } } else { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthSanity() sanity check fail\n")); } LabelOK: if (ChlgText != NULL) os_free_mem(NULL, ChlgText); if (CyperChlgText != NULL) os_free_mem(NULL, CyperChlgText); return; }
INT PMF_EncapBIPAction( IN PRTMP_ADAPTER pAd, IN PUCHAR pMgmtFrame, IN UINT mgmt_len) { PHEADER_802_11 pHdr = (PHEADER_802_11)pMgmtFrame; PPMF_CFG pPmfCfg = NULL; PPMF_MMIE pMMIE; INT idx = 0; PUCHAR pKey = NULL; UCHAR aad_hdr[LEN_PMF_BIP_AAD_HDR]; UCHAR BIP_MIC[LEN_PMF_BIP_MIC]; PUCHAR pFrameBody = &pHdr->Octet[0]; UINT32 body_len = mgmt_len - LENGTH_802_11; /* Sanity check the total frame body length */ if (body_len <= (2 + LEN_PMF_MMIE)) { DBGPRINT(RT_DEBUG_ERROR, ("[PMF]%s : the total length(%d) is too short\n", __FUNCTION__, body_len)); return PMF_ENCAP_BIP_FAILURE; } #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { pPmfCfg = &pAd->ApCfg.MBSSID[MAIN_MBSSID].PmfCfg; } #endif // CONFIG_AP_SUPPORT // /* Sanity check */ if (pPmfCfg == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("[PMF]%s : No related PMF configuation\n", __FUNCTION__)); return PMF_ENCAP_BIP_FAILURE; } if (pPmfCfg && pPmfCfg->MFPC == FALSE) { DBGPRINT(RT_DEBUG_ERROR, ("[PMF]%s : PMF is disabled \n", __FUNCTION__)); return PMF_ENCAP_BIP_FAILURE; } /* Pointer to the position of MMIE */ pMMIE = (PPMF_MMIE)(pMgmtFrame + (mgmt_len - LEN_PMF_MMIE)); /* Select the IGTK currently active for transmission of frames to the intended group of recipients and construct the MMIE (see 7.3.2.55) with the MIC field masked to zero and the KeyID field set to the corresponding IGTK KeyID value. */ if (pPmfCfg->IGTK_KeyIdx == 5) idx = 1; pKey = &pPmfCfg->IGTK[idx][0]; NdisZeroMemory(pMMIE, LEN_PMF_MMIE); /* Bits 0-11 define a value in the range 0-4095. Bits 12 - 15 are reserved and set to 0 on transmission and ignored on reception. The IGTK Key ID is either 4 or 5. The remaining Key IDs are reserved. */ pMMIE->KeyID[0] = pPmfCfg->IGTK_KeyIdx; NdisMoveMemory(pMMIE->IPN, &pPmfCfg->IPN[idx][0], LEN_WPA_TSC); /* The transmitter shall insert a monotonically increasing non-neg- ative integer into the MMIE IPN field. */ INC_TX_TSC(pPmfCfg->IPN[idx], LEN_WPA_TSC); /* Compute AAD */ PMF_ConstructBIPAad((PUCHAR)pHdr, aad_hdr); /* Calculate BIP MIC */ PMF_CalculateBIPMIC(pAd, aad_hdr, pFrameBody, body_len, pKey, BIP_MIC); /* Fill into the MMIE MIC field */ NdisMoveMemory(pMMIE->MIC, BIP_MIC, LEN_PMF_BIP_MIC); /* BIP doesn't need encrypt frame */ pHdr->FC.Wep = 0; return PMF_STATUS_SUCCESS; }
/* ========================================================================== Description: ========================================================================== */ static VOID ApCliPeerAuthRspAtSeq2Action( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { BOOLEAN Cancelled; UCHAR Addr2[MAC_ADDR_LEN]; USHORT Seq, Status, Alg; USHORT RemoteStatus; UCHAR iv_hdr[LEN_WEP_IV_HDR]; /* UCHAR ChlgText[CIPHER_TEXT_LEN]; */ UCHAR *ChlgText = NULL; UCHAR CyperChlgText[CIPHER_TEXT_LEN + 8 + 8]; ULONG c_len = 0; HEADER_802_11 AuthHdr; NDIS_STATUS NState; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; UCHAR ChallengeIe = IE_CHALLENGE_TEXT; UCHAR len_challengeText = CIPHER_TEXT_LEN; USHORT ifIndex = (USHORT)(Elem->Priv); PULONG pCurrState = NULL; #ifdef MAC_REPEATER_SUPPORT UCHAR CliIdx = 0xFF; #endif /* MAC_REPEATER_SUPPORT */ if ((ifIndex >= MAX_APCLI_NUM) #ifdef MAC_REPEATER_SUPPORT && (ifIndex < 64) #endif /* MAC_REPEATER_SUPPORT */ ) return; #ifdef MAC_REPEATER_SUPPORT if (ifIndex >= 64) { CliIdx = ((ifIndex - 64) % 16); ifIndex = ((ifIndex - 64) / 16); pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].AuthCurrState; } else #endif /* MAC_REPEATER_SUPPORT */ pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AuthCurrState; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&ChlgText, CIPHER_TEXT_LEN); if (ChlgText == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); return; } if(PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, (CHAR *) ChlgText)) { if(MAC_ADDR_EQUAL(pAd->ApCfg.ApCliTab[ifIndex].ApCliMlmeAux.Bssid, Addr2) && Seq == 2) { #ifdef MAC_REPEATER_SUPPORT if (CliIdx != 0xFF) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Repeater Cli Receive AUTH_RSP seq#2 to me (Alg=%d, Status=%d)\n", Alg, Status)); RTMPCancelTimer(&pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].ApCliAuthTimer, &Cancelled); } else #endif /* MAC_REPEATER_SUPPORT */ { DBGPRINT(RT_DEBUG_TRACE, ("APCLI AUTH - Receive AUTH_RSP seq#2 to me (Alg=%d, Status=%d)\n", Alg, Status)); RTMPCancelTimer(&pAd->ApCfg.ApCliTab[ifIndex].ApCliMlmeAux.ApCliAuthTimer, &Cancelled); } if(Status == MLME_SUCCESS) { if(pAd->ApCfg.ApCliTab[ifIndex].ApCliMlmeAux.Alg == Ndis802_11AuthModeOpen) { *pCurrState = APCLI_AUTH_REQ_IDLE; ApCliCtrlMsg.Status= MLME_SUCCESS; #ifdef MAC_REPEATER_SUPPORT ApCliCtrlMsg.CliIdx = CliIdx; ApCliCtrlMsg.BssIdx = ifIndex; ifIndex = (USHORT)(Elem->Priv); #endif /* MAC_REPEATER_SUPPORT */ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_AUTH_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } else { PCIPHER_KEY pKey; UINT default_key = pAd->ApCfg.ApCliTab[ifIndex].DefaultKeyId; pKey = &pAd->ApCfg.ApCliTab[ifIndex].SharedKey[default_key]; /* 2. shared key, need to be challenged */ Seq++; RemoteStatus = MLME_SUCCESS; /* allocate and send out AuthRsp frame */ NState = MlmeAllocateMemory(pAd, &pOutBuffer); if(NState != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - ApCliPeerAuthRspAtSeq2Action allocate memory fail\n")); *pCurrState = APCLI_AUTH_REQ_IDLE; ApCliCtrlMsg.Status= MLME_FAIL_NO_RESOURCE; #ifdef MAC_REPEATER_SUPPORT ApCliCtrlMsg.CliIdx = CliIdx; ApCliCtrlMsg.BssIdx = ifIndex; ifIndex = (USHORT)(Elem->Priv); #endif /* MAC_REPEATER_SUPPORT */ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_AUTH_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); goto LabelOK; } #ifdef MAC_REPEATER_SUPPORT if (CliIdx != 0xFF) DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Repeater Cli Send AUTH request seq#3...\n")); else #endif /* MAC_REPEATER_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH request seq#3...\n")); ApCliMgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr2, pAd->ApCfg.ApCliTab[ifIndex].ApCliMlmeAux.Bssid, ifIndex); AuthHdr.FC.Wep = 1; #ifdef MAC_REPEATER_SUPPORT if (CliIdx != 0xFF) COPY_MAC_ADDR(AuthHdr.Addr2, pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].CurrentAddress); #endif /* MAC_REPEATER_SUPPORT */ /* Encrypt challenge text & auth information */ /* TSC increment */ INC_TX_TSC(pKey->TxTsc, LEN_WEP_TSC); /* Construct the 4-bytes WEP IV header */ RTMPConstructWEPIVHdr(default_key, pKey->TxTsc, iv_hdr); Alg = cpu2le16(*(USHORT *)&Alg); Seq = cpu2le16(*(USHORT *)&Seq); RemoteStatus= cpu2le16(*(USHORT *)&RemoteStatus); /* Construct message text */ MakeOutgoingFrame(CyperChlgText, &c_len, 2, &Alg, 2, &Seq, 2, &RemoteStatus, 1, &ChallengeIe, 1, &len_challengeText, len_challengeText, ChlgText, END_OF_ARGS); if (RTMPSoftEncryptWEP(pAd, iv_hdr, pKey, CyperChlgText, c_len) == FALSE) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - ApCliPeerAuthRspAtSeq2Action allocate memory fail\n")); *pCurrState = APCLI_AUTH_REQ_IDLE; ApCliCtrlMsg.Status= MLME_FAIL_NO_RESOURCE; #ifdef MAC_REPEATER_SUPPORT ApCliCtrlMsg.BssIdx = ifIndex; ApCliCtrlMsg.CliIdx = CliIdx; ifIndex = (USHORT)(Elem->Priv); #endif /* MAC_REPEATER_SUPPORT */ MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_AUTH_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); goto LabelOK; } /* Update the total length for 4-bytes ICV */ c_len += LEN_ICV; MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &AuthHdr, LEN_WEP_IV_HDR, iv_hdr, c_len, CyperChlgText, END_OF_ARGS); MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); #ifdef MAC_REPEATER_SUPPORT if (CliIdx != 0xFF) RTMPSetTimer(&pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].ApCliAuthTimer, AUTH_TIMEOUT); else #endif /* MAC_REPEATER_SUPPORT */ RTMPSetTimer(&pAd->ApCfg.ApCliTab[ifIndex].ApCliMlmeAux.ApCliAuthTimer, AUTH_TIMEOUT); *pCurrState = APCLI_AUTH_WAIT_SEQ4; } } else { *pCurrState = APCLI_AUTH_REQ_IDLE; #ifdef MAC_REPEATER_SUPPORT ApCliCtrlMsg.CliIdx = CliIdx; ApCliCtrlMsg.BssIdx = ifIndex; ifIndex = (USHORT)(Elem->Priv); #endif /* MAC_REPEATER_SUPPORT */ ApCliCtrlMsg.Status= Status; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_AUTH_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } } } else { DBGPRINT(RT_DEBUG_TRACE, ("APCLI AUTH - PeerAuthSanity() sanity check fail\n")); } LabelOK: if (pOutBuffer != NULL) MlmeFreeMemory(pAd, pOutBuffer); if (ChlgText != NULL) os_free_mem(NULL, ChlgText); return; }
INT PMF_EncryptUniRobustFrameAction( IN PRTMP_ADAPTER pAd, IN PUCHAR pMgmtFrame, IN UINT mgmt_len) { PMAC_TABLE_ENTRY pEntry = NULL; PHEADER_802_11 pHdr = (PHEADER_802_11)pMgmtFrame; INT data_len; PUCHAR pBuf; INT Status; /* Check if the length is valid */ data_len = mgmt_len - (LENGTH_802_11 + LEN_CCMP_HDR + LEN_CCMP_MIC); if (data_len <= 0) { DBGPRINT(RT_DEBUG_ERROR, ("%s : The payload length(%d) is invalid\n", __FUNCTION__, data_len)); return PMF_UNICAST_ENCRYPT_FAILURE; } /* Look up the entry through Address 1 of 802.11 header */ #ifdef CONFIG_AP_SUPPORT pEntry = MacTableLookup(pAd, pHdr->Addr1); #endif /* CONFIG_AP_SUPPORT */ if (pEntry == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s : The entry doesn't exist\n", __FUNCTION__)); return PMF_UNICAST_ENCRYPT_FAILURE; } /* check the PMF capable for this entry */ if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_PMF_CAPABLE) == FALSE) { DBGPRINT(RT_DEBUG_ERROR,("%s : the entry no PMF capable !\n", __FUNCTION__)); return PMF_UNICAST_ENCRYPT_FAILURE; } /* Allocate a buffer for building PMF packet */ Status = MlmeAllocateMemory(pAd, &pBuf); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_ERROR,("%s : allocate PMF buffer fail!\n", __FUNCTION__)); return PMF_UNICAST_ENCRYPT_FAILURE; } /* Construct and insert 8-bytes CCMP header to MPDU header */ RTMPConstructCCMPHdr(0, pEntry->PmfTxTsc, pBuf); NdisMoveMemory(pBuf + LEN_CCMP_HDR, &pHdr->Octet[0], data_len); // Encrypt the MPDU data by software RTMPSoftEncryptCCMP(pAd, (PUCHAR)pHdr, pEntry->PmfTxTsc, pEntry->PairwiseKey.Key, pBuf + LEN_CCMP_HDR, data_len); data_len += (LEN_CCMP_HDR + LEN_CCMP_MIC); NdisMoveMemory(&pHdr->Octet[0], pBuf, data_len); /* TSC increment for next transmittion */ INC_TX_TSC(pEntry->PmfTxTsc, LEN_WPA_TSC); MlmeFreeMemory(pAd, pBuf); return PMF_STATUS_SUCCESS; }