[WCNCR00152277] softap: add 802.11w PMF mandatory item for AP role
[Description]
Add 802.11w PMF feature
Change-Id: Ia35840b65ba244fde0b11077f08c87a19de24353
Signed-off-by: Bennett Ou <bennett.ou@mediatek.com>
CR-Id: WCNCR00152277
Feature: sofap/pmf
diff --git a/common/wlan_oid.c b/common/wlan_oid.c
index 53a66cf..72696aa 100644
--- a/common/wlan_oid.c
+++ b/common/wlan_oid.c
@@ -2354,6 +2354,15 @@
&prCmdKey->aucKeyMaterial[24], MIC_KEY_LEN);
}
}
+ } else {
+#if CFG_SUPPORT_802_11W
+ /* AP PMF */
+ if ((prCmdKey->ucKeyId >= 4 && prCmdKey->ucKeyId <= 5) &&
+ (prCmdKey->ucAlgorithmId == CIPHER_SUITE_BIP)) {
+ DBGLOG(RSN, INFO, "AP mode set BIP\n");
+ prBssInfo->rApPmfCfg.fgBipKeyInstalled = TRUE;
+ }
+#endif
}
} else { /* Legacy windows NDIS no cipher info */
#if 0
@@ -2441,10 +2450,16 @@
#endif
#if CFG_SUPPORT_802_11W
+ /* AP PMF */
+ /* 20170519 BIP optional item is not support now */
+ DBGLOG(RSN, INFO, "802.11w BIP optional not support now\n");
+ if ((prNewKey->u4KeyIndex & 0xff) >= 4)
+ return WLAN_STATUS_SUCCESS;
+
if (prCmdKey->ucAlgorithmId == CIPHER_SUITE_BIP) {
if (prCmdKey->ucIsAuthenticator) {
- DBGLOG(RSN, ERROR, "Not support 111w AP mode ");
- ASSERT(FALSE);
+ DBGLOG(RSN, INFO, "Authenticator follow AIS method\n");
+
}
prCmdKey->ucWlanIndex =
secPrivacySeekForBcEntry(prAdapter,
@@ -2453,6 +2468,7 @@
prBssInfo->prStaRecOfAP->ucIndex,
prCmdKey->ucAlgorithmId, prCmdKey->ucKeyId);
+ DBGLOG(RSN, INFO, "BIP BC wtbl index:%d\n", prCmdKey->ucWlanIndex);
} else
#endif
if (1) {
@@ -2466,6 +2482,12 @@
prCmdKey->ucWlanIndex = prStaRec->ucWlanIndex;
prStaRec->fgTransmitKeyExist = TRUE; /* wait for CMD Done ? */
kalMemCopy(prCmdKey->aucPeerAddr, prNewKey->arBSSID, MAC_ADDR_LEN);
+#if CFG_SUPPORT_802_11W
+ /* AP PMF */
+ DBGLOG(RSN, INFO, "Assign client PMF flag = %d\n",
+ prStaRec->rPmfCfg.fgApplyPmf);
+ prCmdKey->ucMgmtProtection = prStaRec->rPmfCfg.fgApplyPmf;
+#endif
} else {
ASSERT(FALSE);
}
@@ -2790,7 +2812,7 @@
prGlueInfo = prAdapter->prGlueInfo;
prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prDefaultKey->ucBssIdx);
- /* DBGLOG(RSN, LOUD, "WlanIdx = %d\n", prBssInfo->wepkeyWlanIdx); */
+ DBGLOG(RSN, INFO, "WlanIdx = %d\n", prBssInfo->wepkeyWlanIdx);
if (prDefaultKey->ucMulticast) {
if (!prBssInfo)
diff --git a/include/mgmt/cnm_mem.h b/include/mgmt/cnm_mem.h
index 4a0292e..ed3df96 100644
--- a/include/mgmt/cnm_mem.h
+++ b/include/mgmt/cnm_mem.h
@@ -211,6 +211,34 @@
OS_SYSTIME rReceiveLifetimeLimit; /* The receive time of 1st fragment */
} FRAG_INFO_T, *P_FRAG_INFO_T;
+#if CFG_SUPPORT_802_11W
+/* AP PMF */
+struct AP_PMF_CFG {
+ BOOLEAN fgMfpc;
+ BOOLEAN fgMfpr;
+ BOOLEAN fgSha256;
+ BOOLEAN fgAPApplyPmfReq;
+ BOOLEAN fgBipKeyInstalled;
+};
+
+struct STA_PMF_CFG {
+ BOOLEAN fgMfpc;
+ BOOLEAN fgMfpr;
+ BOOLEAN fgSha256;
+ BOOLEAN fgApplyPmf;
+ BOOLEAN fgBipKeyInstalled;
+ BOOLEAN fgRxDeauthResp; /* for certification 4.3.3.1, 4.3.3.2 TX unprotected deauth */
+
+ /* For PMF SA query TX request retry a timer */
+ UINT_32 u4SAQueryStart; /* record the start time of 1st SAQ request */
+ UINT_32 u4SAQueryCount;
+ UINT_8 ucSAQueryTimedOut; /* retry more than 1000ms */
+ TIMER_T rSAQueryTimer;
+ UINT_16 u2TransactionID;
+
+};
+#endif
+
/* Define STA record structure */
struct _STA_RECORD_T {
LINK_ENTRY_T rLinkEntry;
@@ -518,6 +546,10 @@
UINT_8 ucSmDialogToken; /* Spectrum Mngt Dialog Token */
UINT_8 ucSmMsmtRequestMode; /* Measurement Request Mode */
UINT_8 ucSmMsmtToken; /* Measurement Request Token */
+#if CFG_SUPPORT_802_11W
+ /* AP PMF */
+ struct STA_PMF_CFG rPmfCfg;
+#endif
};
#if 0
diff --git a/include/mgmt/rsn.h b/include/mgmt/rsn.h
index 0281a5b..be94150 100644
--- a/include/mgmt/rsn.h
+++ b/include/mgmt/rsn.h
@@ -160,6 +160,7 @@
#define WPA_IE(fp) ((P_WPA_INFO_ELEM_T) fp)
#define ELEM_MAX_LEN_ASSOC_RSP_WSC_IE (32 - ELEM_HDR_LEN)
+#define ELEM_MAX_LEN_TIMEOUT_IE (5)
/*******************************************************************************
* F U N C T I O N D E C L A R A T I O N S
@@ -188,7 +189,8 @@
IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType, OUT PUINT_16 pu2SubTypeVersion);
#if CFG_SUPPORT_AAA
-void rsnParserCheckForRSNCCMPPSK(P_ADAPTER_T prAdapter, P_RSN_INFO_ELEM_T prIe, PUINT_16 pu2StatusCode);
+void rsnParserCheckForRSNCCMPPSK(P_ADAPTER_T prAdapter, P_RSN_INFO_ELEM_T prIe, P_STA_RECORD_T prStaRec,
+ PUINT_16 pu2StatusCode);
#endif
VOID rsnTkipHandleMICFailure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgErrorKeyType);
@@ -224,7 +226,16 @@
void rsnSaQueryRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
void rsnSaQueryAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
-#endif
+
+UINT_16 rsnPmfCapableValidation(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec);
+
+VOID rsnPmfGenerateTimeoutIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo);
+
+void rsnApStartSaQuery(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec);
+
+void rsnApSaQueryAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb);
+
+#endif /* CFG_SUPPORT_802_11W */
#if CFG_SUPPORT_AAA
VOID rsnGenerateWSCIEForAssocRsp(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo);
diff --git a/include/nic/adapter.h b/include/nic/adapter.h
index 777003d..4dd1c45 100644
--- a/include/nic/adapter.h
+++ b/include/nic/adapter.h
@@ -474,6 +474,11 @@
ENUM_BAND_T eBandGranted;
UINT_8 ucPrimaryChannelGranted;
PARAM_CUSTOM_ACL rACL;
+
+#if CFG_SUPPORT_802_11W
+ /* AP PMF */
+ struct AP_PMF_CFG rApPmfCfg;
+#endif
};
struct _AIS_SPECIFIC_BSS_INFO_T {
diff --git a/include/nic_cmd_event.h b/include/nic_cmd_event.h
index 419283b..27dca40 100644
--- a/include/nic_cmd_event.h
+++ b/include/nic_cmd_event.h
@@ -1014,7 +1014,7 @@
UINT_8 ucKeyId;
UINT_8 ucKeyLen;
UINT_8 ucWlanIndex;
- UINT_8 ucReverved;
+ UINT_8 ucMgmtProtection;
UINT_8 aucKeyMaterial[32];
UINT_8 aucKeyRsc[16];
} CMD_802_11_KEY, *P_CMD_802_11_KEY;
diff --git a/mgmt/aaa_fsm.c b/mgmt/aaa_fsm.c
index 83522b9..3e9b48d 100644
--- a/mgmt/aaa_fsm.c
+++ b/mgmt/aaa_fsm.c
@@ -447,8 +447,10 @@
P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
UINT_16 u2StatusCode = STATUS_CODE_RESERVED;
BOOLEAN fgReplyAssocResp = FALSE;
+ BOOLEAN fgSendSAQ = FALSE;
ASSERT(prAdapter);
+ DBGLOG(AAA, INFO, "aaaFsmRunEventRxAssoc\n");
do {
@@ -604,13 +606,24 @@
}
#endif
} else {
- prStaRec->u2AssocId = 0; /* Invalid Association ID */
- /* If (Re)association fail, remove sta record and use class error to handle sta */
- prStaRec->eAuthAssocState = AA_STATE_IDLE;
+#if CFG_SUPPORT_802_11W
+ /* AP PMF */
+ /* don't change state, just send assoc resp (NO need TX done, TIE + code30) and then SAQ */
+ if (u2StatusCode == STATUS_CODE_ASSOC_REJECTED_TEMPORARILY) {
+ DBGLOG(AAA, INFO, "AP send SAQ\n");
+ fgSendSAQ = TRUE;
+ } else
+#endif
+ {
+ prStaRec->u2AssocId = 0; /* Invalid Association ID */
- /* NOTE(Kevin): Better to change state here, not at TX Done */
- cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
+ /* If (Re)association fail, remove sta record and use class error to handle sta */
+ prStaRec->eAuthAssocState = AA_STATE_IDLE;
+
+ /* NOTE(Kevin): Better to change state here, not at TX Done */
+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2);
+ }
}
/* Update the record join time. */
@@ -623,6 +636,14 @@
/* 4 <4.2> Reply Assoc Resp */
assocSendReAssocRespFrame(prAdapter, prStaRec);
+#if CFG_SUPPORT_802_11W
+ /* AP PMF */
+ if (fgSendSAQ) {
+ /* if PMF connection, and return code 30, send SAQ */
+ rsnApStartSaQuery(prAdapter, prStaRec);
+ }
+#endif
+
}
return WLAN_STATUS_SUCCESS;
diff --git a/mgmt/assoc.c b/mgmt/assoc.c
index b73009e..c6da3e3 100644
--- a/mgmt/assoc.c
+++ b/mgmt/assoc.c
@@ -161,6 +161,10 @@
#if CFG_SUPPORT_MTK_SYNERGY
{(ELEM_HDR_LEN + ELEM_MIN_LEN_MTK_OUI), NULL, rlmGenerateMTKOuiIE} /* 221 */
#endif
+ ,
+#if CFG_SUPPORT_802_11W
+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_TIMEOUT_IE), NULL, rsnPmfGenerateTimeoutIE} /* 56 */
+#endif
};
#endif /* CFG_SUPPORT_AAA */
@@ -962,6 +966,8 @@
ASSERT(prStaRec);
ASSERT(prStaRec->ucBssIndex <= MAX_BSS_INDEX);
+ DBGLOG(RSN, INFO, "assocSendDisAssocFrame\n");
+
/* 4 <1> Allocate a PKT_INFO_T for Disassociation Frame */
/* Init with MGMT Header Length + Length of Fixed Fields + IE Length */
u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN;
@@ -981,12 +987,18 @@
MAC_TX_RESERVED_FIELD), pucMacAddress, u2ReasonCode);
#if CFG_SUPPORT_802_11W
+ /* AP PMF */
if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) {
- P_WLAN_DISASSOC_FRAME_T prDisassocFrame;
+ /* PMF certification 4.3.3.1, 4.3.3.2 send unprotected deauth reason 6/7 */
+ if (prStaRec->rPmfCfg.fgRxDeauthResp != TRUE) {
- prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
+ P_WLAN_DISASSOC_FRAME_T prDisassocFrame;
- prDisassocFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
+ prDisassocFrame =
+ (P_WLAN_DISASSOC_FRAME_T) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
+
+ prDisassocFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
+ }
}
#endif
@@ -1000,9 +1012,16 @@
WLAN_MAC_MGMT_HEADER_LEN, WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, NULL, MSDU_RATE_MODE_AUTO);
#if CFG_SUPPORT_802_11W
+ /* AP PMF */
+ /* caution: access prStaRec only if true */
if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) {
- /* DBGLOG(RSN, TRACE, ("Set MSDU_OPT_PROTECTED_FRAME\n")); */
- nicTxConfigPktOption(prMsduInfo, MSDU_OPT_PROTECTED_FRAME, TRUE);
+ /* 4.3.3.1 send unprotected deauth reason 6/7 */
+ if (prStaRec->rPmfCfg.fgRxDeauthResp != TRUE) {
+ DBGLOG(RSN, INFO, "Disassoc Set MSDU_OPT_PROTECTED_FRAME\n");
+ nicTxConfigPktOption(prMsduInfo, MSDU_OPT_PROTECTED_FRAME, TRUE);
+ }
+
+ prStaRec->rPmfCfg.fgRxDeauthResp = FALSE;
}
#endif
@@ -1051,6 +1070,7 @@
MAC2STR(prDisassocFrame->aucSrcAddr));
return WLAN_STATUS_FAILURE;
}
+
/* 4 <3> Parse the Fixed Fields of Deauthentication Frame Body. */
WLAN_GET_FIELD_16(&prDisassocFrame->u2ReasonCode, &u2RxReasonCode);
*pu2ReasonCode = u2RxReasonCode;
@@ -1190,7 +1210,7 @@
#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK
if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) {
prIeRsn = RSN_IE(pucIE);
- rsnParserCheckForRSNCCMPPSK(prAdapter, prIeRsn, &u2StatusCode);
+ rsnParserCheckForRSNCCMPPSK(prAdapter, prIeRsn, prStaRec, &u2StatusCode);
if (u2StatusCode != STATUS_CODE_SUCCESSFUL) {
*pu2StatusCode = u2StatusCode;
return WLAN_STATUS_SUCCESS;
diff --git a/mgmt/auth.c b/mgmt/auth.c
index f6db0de..79f1320 100644
--- a/mgmt/auth.c
+++ b/mgmt/auth.c
@@ -798,6 +798,8 @@
UINT_8 ucBssIndex = BSS_INFO_NUM;
UINT_8 aucBMC[] = BC_MAC_ADDR;
+ DBGLOG(RSN, INFO, "authSendDeauthFrame\n");
+
/* NOTE(Kevin): The best way to reply the Deauth is according to the incoming data
* frame
*/
@@ -905,13 +907,23 @@
pucBssid, u2ReasonCode);
#if CFG_SUPPORT_802_11W
+ /* AP PMF */
if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) {
- P_WLAN_DEAUTH_FRAME_T prDeauthFrame;
+ /* PMF certification 4.3.3.1, 4.3.3.2 send unprotected deauth reason 6/7 */
+ /* if (AP mode & not for PMF reply case) OR (STA PMF) */
+ if (((GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex)->eCurrentOPMode ==
+ OP_MODE_ACCESS_POINT) &&
+ (prStaRec->rPmfCfg.fgRxDeauthResp != TRUE)) ||
+ (GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex)->eNetworkType ==
+ (UINT_8) NETWORK_TYPE_AIS)) {
- prDeauthFrame =
- (P_WLAN_DEAUTH_FRAME_T) (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
+ P_WLAN_DEAUTH_FRAME_T prDeauthFrame;
- prDeauthFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
+ prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) (PUINT_8) ((ULONG) (prMsduInfo->prPacket) +
+ MAC_TX_RESERVED_FIELD);
+
+ prDeauthFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
+ }
}
#endif
nicTxSetPktLifeTime(prMsduInfo, 100);
@@ -927,8 +939,17 @@
WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN, pfTxDoneHandler, MSDU_RATE_MODE_AUTO);
#if CFG_SUPPORT_802_11W
- if (rsnCheckBipKeyInstalled(prAdapter, prStaRec))
- nicTxConfigPktOption(prMsduInfo, MSDU_OPT_PROTECTED_FRAME, TRUE);
+ /* AP PMF */
+ /* caution: access prStaRec only if true */
+ if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) {
+ /* 4.3.3.1 send unprotected deauth reason 6/7 */
+ if (prStaRec->rPmfCfg.fgRxDeauthResp != TRUE) {
+ DBGLOG(RSN, INFO, "Deauth Set MSDU_OPT_PROTECTED_FRAME\n");
+ nicTxConfigPktOption(prMsduInfo, MSDU_OPT_PROTECTED_FRAME, TRUE);
+ }
+
+ prStaRec->rPmfCfg.fgRxDeauthResp = FALSE;
+ }
#endif
diff --git a/mgmt/p2p_func.c b/mgmt/p2p_func.c
index f85d6e6..6100891 100644
--- a/mgmt/p2p_func.c
+++ b/mgmt/p2p_func.c
@@ -2435,6 +2435,8 @@
PUINT_8 pucIE = (PUINT_8) NULL;
UINT_16 u2Offset = 0;
P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL;
+ UINT_8 i = 0;
+ RSN_INFO_T rRsnIe;
do {
ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL));
@@ -2590,20 +2592,40 @@
}
break;
case ELEM_ID_RSN: /* 48 *//* V */
- {
- RSN_INFO_T rRsnIe;
- DBGLOG(P2P, TRACE, "RSN IE\n");
- kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_CCMP,
- (UINT_8) prP2pBssInfo->u4PrivateData);
+ DBGLOG(P2P, TRACE, "RSN IE\n");
+ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_CCMP,
+ (UINT_8) prP2pBssInfo->u4PrivateData);
- if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &rRsnIe)) {
- prP2pBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP;
- prP2pBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP;
- prP2pBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK;
- prP2pBssInfo->u2RsnSelectedCapInfo = rRsnIe.u2RsnCap;
+ if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &rRsnIe)) {
+ prP2pBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP;
+ prP2pBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP;
+ prP2pBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK;
+ prP2pBssInfo->u2RsnSelectedCapInfo = rRsnIe.u2RsnCap;
+ }
+
+#if CFG_SUPPORT_802_11W
+ /* AP PMF */
+ prP2pBssInfo->rApPmfCfg.fgMfpc = (rRsnIe.u2RsnCap & ELEM_WPA_CAP_MFPC) ? 1 : 0;
+ prP2pBssInfo->rApPmfCfg.fgMfpr = (rRsnIe.u2RsnCap & ELEM_WPA_CAP_MFPR) ? 1 : 0;
+
+ for (i = 0; i < rRsnIe.u4AuthKeyMgtSuiteCount; i++) {
+ if ((rRsnIe.au4AuthKeyMgtSuite[i] == RSN_AKM_SUITE_PSK_SHA256) ||
+ (rRsnIe.au4AuthKeyMgtSuite[i] == RSN_AKM_SUITE_802_1X_SHA256)) {
+ DBGLOG(RSN, INFO, "SHA256 support\n");
+ /* over-write u4RsnSelectedAKMSuite by SHA256 AKM */
+ prP2pBssInfo->u4RsnSelectedAKMSuite =
+ rRsnIe.au4AuthKeyMgtSuite[i];
+ prP2pBssInfo->rApPmfCfg.fgSha256 = TRUE;
+ break;
}
}
+ DBGLOG(RSN, ERROR, "bcn mfpc:%d, mfpr:%d, sha256:%d\n",
+ prP2pBssInfo->rApPmfCfg.fgMfpc,
+ prP2pBssInfo->rApPmfCfg.fgMfpr,
+ prP2pBssInfo->rApPmfCfg.fgSha256);
+#endif
+
break;
case ELEM_ID_EXTENDED_SUP_RATES: /* 50 *//* V */
/* ELEM_ID_SUP_RATES should be placed before ELEM_ID_EXTENDED_SUP_RATES. */
diff --git a/mgmt/p2p_role_fsm.c b/mgmt/p2p_role_fsm.c
index 70b65b4..501d26e 100644
--- a/mgmt/p2p_role_fsm.c
+++ b/mgmt/p2p_role_fsm.c
@@ -585,6 +585,7 @@
{
P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
UINT_16 u2ReasonCode = 0;
+ BOOLEAN fgSendDeauth = FALSE; /* flag to send deauth when rx sta disassc/deauth */
do {
ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL));
@@ -650,9 +651,29 @@
/* Delete client from client list. */
if (authProcessRxDeauthFrame(prSwRfb,
prP2pBssInfo->aucBSSID, &u2ReasonCode) == WLAN_STATUS_SUCCESS) {
+
+#if CFG_SUPPORT_802_11W
+ /* AP PMF */
+ if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) {
+ if (HAL_RX_STATUS_IS_CIPHER_MISMATCH(prSwRfb->prRxStatus) ||
+ HAL_RX_STATUS_IS_CLM_ERROR(prSwRfb->prRxStatus)) {
+ /* if cipher mismatch, or incorrect encrypt, just drop */
+ DBGLOG(P2P, ERROR, "Rx deauth CM/CLM=1\n");
+ return;
+ }
+
+ /* 4.3.3.1 send unprotected deauth reason 6/7 */
+ DBGLOG(P2P, INFO, "deauth reason=6\n");
+ fgSendDeauth = TRUE;
+ u2ReasonCode = REASON_CODE_CLASS_2_ERR;
+ prStaRec->rPmfCfg.fgRxDeauthResp = TRUE;
+ }
+#endif
+
if (bssRemoveClient(prAdapter, prP2pBssInfo, prStaRec)) {
/* Indicate disconnect to Host. */
- p2pFuncDisconnect(prAdapter, prP2pBssInfo, prStaRec, FALSE, u2ReasonCode);
+ p2pFuncDisconnect(prAdapter, prP2pBssInfo, prStaRec, fgSendDeauth,
+ u2ReasonCode);
/* Deactive BSS if PWR is IDLE and no peer */
if (IS_NET_PWR_STATE_IDLE(prAdapter, prP2pBssInfo->ucBssIndex) &&
(bssGetClientCount(prAdapter, prP2pBssInfo) == 0)) {
@@ -678,6 +699,7 @@
{
P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
UINT_16 u2ReasonCode = 0;
+ BOOLEAN fgSendDeauth = FALSE; /* flag to send deauth when rx sta disassc/deauth */
do {
ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL));
@@ -743,9 +765,29 @@
if (assocProcessRxDisassocFrame(prAdapter,
prSwRfb,
prP2pBssInfo->aucBSSID, &u2ReasonCode) == WLAN_STATUS_SUCCESS) {
+
+#if CFG_SUPPORT_802_11W
+ /* AP PMF */
+ if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) {
+ if (HAL_RX_STATUS_IS_CIPHER_MISMATCH(prSwRfb->prRxStatus) ||
+ HAL_RX_STATUS_IS_CLM_ERROR(prSwRfb->prRxStatus)) {
+ /* if cipher mismatch, or incorrect encrypt, just drop */
+ DBGLOG(P2P, ERROR, "Rx disassoc CM/CLM=1\n");
+ return;
+ }
+
+ /* 4.3.3.1 send unprotected deauth reason 6/7 */
+ DBGLOG(P2P, INFO, "deauth reason=6\n");
+ fgSendDeauth = TRUE;
+ u2ReasonCode = REASON_CODE_CLASS_2_ERR;
+ prStaRec->rPmfCfg.fgRxDeauthResp = TRUE;
+ }
+#endif
+
if (bssRemoveClient(prAdapter, prP2pBssInfo, prStaRec)) {
/* Indicate disconnect to Host. */
- p2pFuncDisconnect(prAdapter, prP2pBssInfo, prStaRec, FALSE, u2ReasonCode);
+ p2pFuncDisconnect(prAdapter, prP2pBssInfo, prStaRec, fgSendDeauth,
+ u2ReasonCode);
/* Deactive BSS if PWR is IDLE and no peer */
if (IS_NET_PWR_STATE_IDLE(prAdapter, prP2pBssInfo->ucBssIndex) &&
(bssGetClientCount(prAdapter, prP2pBssInfo) == 0)) {
diff --git a/mgmt/rsn.c b/mgmt/rsn.c
index c34ca52..101fc52 100644
--- a/mgmt/rsn.c
+++ b/mgmt/rsn.c
@@ -1307,6 +1307,19 @@
} else {
DBGLOG(RSN, TRACE, "!RSN_AUTH_MFP - No MFPC!\n");
}
+ } else if ((GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->eNetworkType == NETWORK_TYPE_P2P) &&
+ (GET_BSS_INFO_BY_INDEX(prAdapter, ucBssIndex)->eCurrentOPMode ==
+ (UINT_8) OP_MODE_ACCESS_POINT)) {
+ /* AP PMF */
+ if (prBssInfo->rApPmfCfg.fgMfpr) {
+ WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC | ELEM_WPA_CAP_MFPR); /* Capabilities */
+ DBGLOG(RSN, TRACE, "AP RSN_AUTH_MFP - MFPC & MFPR\n");
+ } else if (prBssInfo->rApPmfCfg.fgMfpc) {
+ WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC); /* Capabilities */
+ DBGLOG(RSN, TRACE, "AP RSN_AUTH_MFP - MFPC\n");
+ } else {
+ DBGLOG(RSN, TRACE, "!AP RSN_AUTH_MFP - No MFPC!\n");
+ }
}
#else
/* Capabilities */
@@ -1435,13 +1448,18 @@
* \retval none
*/
/*----------------------------------------------------------------------------*/
-void rsnParserCheckForRSNCCMPPSK(P_ADAPTER_T prAdapter, P_RSN_INFO_ELEM_T prIe, PUINT_16 pu2StatusCode)
+void rsnParserCheckForRSNCCMPPSK(P_ADAPTER_T prAdapter, P_RSN_INFO_ELEM_T prIe,
+ P_STA_RECORD_T prStaRec, PUINT_16 pu2StatusCode)
{
RSN_INFO_T rRsnIe;
+ P_BSS_INFO_T prBssInfo;
+ UINT_8 i;
+ UINT_16 statusCode;
ASSERT(prAdapter);
ASSERT(prIe);
+ ASSERT(prStaRec);
ASSERT(pu2StatusCode);
*pu2StatusCode = STATUS_CODE_INVALID_INFO_ELEMENT;
@@ -1464,6 +1482,44 @@
DBGLOG(RSN, TRACE, "RSN with CCMP-PSK\n");
*pu2StatusCode = WLAN_STATUS_SUCCESS;
+
+#if CFG_SUPPORT_802_11W
+ /* AP PMF */
+ /* 1st check: if already PMF connection, reject assoc req: error 30 ASSOC_REJECTED_TEMPORARILY */
+ if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) {
+ *pu2StatusCode = STATUS_CODE_ASSOC_REJECTED_TEMPORARILY;
+ return;
+ }
+
+ /* if RSN capability not exist, just return */
+ if (!rRsnIe.fgRsnCapPresent) {
+ *pu2StatusCode = WLAN_STATUS_SUCCESS;
+ return;
+ }
+
+ prStaRec->rPmfCfg.fgMfpc = (rRsnIe.u2RsnCap & ELEM_WPA_CAP_MFPC) ? 1 : 0;
+ prStaRec->rPmfCfg.fgMfpr = (rRsnIe.u2RsnCap & ELEM_WPA_CAP_MFPR) ? 1 : 0;
+
+ for (i = 0; i < rRsnIe.u4AuthKeyMgtSuiteCount; i++) {
+ if ((rRsnIe.au4AuthKeyMgtSuite[i] == RSN_AKM_SUITE_802_1X_SHA256) ||
+ (rRsnIe.au4AuthKeyMgtSuite[i] == RSN_AKM_SUITE_PSK_SHA256)) {
+ DBGLOG(RSN, INFO, "STA SHA256 support\n");
+ prStaRec->rPmfCfg.fgSha256 = TRUE;
+ break;
+ }
+ }
+
+ DBGLOG(RSN, INFO, "STA Assoc req mfpc:%d, mfpr:%d, sha256:%d, bssIndex:%d, applyPmf:%d\n",
+ prStaRec->rPmfCfg.fgMfpc, prStaRec->rPmfCfg.fgMfpr,
+ prStaRec->rPmfCfg.fgSha256, prStaRec->ucBssIndex, prStaRec->rPmfCfg.fgApplyPmf);
+
+
+ prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex);
+
+ /* if PMF validation fail, return success as legacy association */
+ statusCode = rsnPmfCapableValidation(prAdapter, prBssInfo, prStaRec);
+ *pu2StatusCode = statusCode;
+#endif
}
}
@@ -1968,11 +2024,21 @@
/*----------------------------------------------------------------------------*/
UINT_32 rsnCheckBipKeyInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
{
- if (prStaRec
- && GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex)->eNetworkType == (UINT_8) NETWORK_TYPE_AIS)
- return prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled;
- else
+ /* caution: prStaRec might be null ! */
+ if (prStaRec) {
+ if (GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex)->eNetworkType == (UINT_8) NETWORK_TYPE_AIS) {
+ return prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled;
+ } else if ((GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex)->eNetworkType == NETWORK_TYPE_P2P) &&
+ (GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex)->eCurrentOPMode ==
+ OP_MODE_ACCESS_POINT)) {
+ DBGLOG(RSN, INFO, "AP-STA PMF capable:%d\n", prStaRec->rPmfCfg.fgApplyPmf);
+ return prStaRec->rPmfCfg.fgApplyPmf;
+ } else {
+ return FALSE;
+ }
+ } else
return FALSE;
+
}
/*----------------------------------------------------------------------------*/
@@ -2393,3 +2459,403 @@
}
#endif
+
+#if CFG_SUPPORT_802_11W
+/* AP PMF */
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to validate setting if PMF connection capable or not
+* If AP MFPC=1, and STA MFPC=1, we let this as PMF connection
+*
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+UINT_16 rsnPmfCapableValidation(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec)
+{
+ BOOLEAN selfMfpc, selfMfpr, peerMfpc, peerMfpr;
+
+ selfMfpc = prBssInfo->rApPmfCfg.fgMfpc;
+ selfMfpr = prBssInfo->rApPmfCfg.fgMfpr;
+ peerMfpc = prStaRec->rPmfCfg.fgMfpc;
+ peerMfpr = prStaRec->rPmfCfg.fgMfpr;
+
+ DBGLOG(RSN, INFO, "AP mfpc:%d, mfpr:%d / STA mfpc:%d, mfpr:%d\n",
+ selfMfpc, selfMfpr, peerMfpc, peerMfpr);
+
+ if ((selfMfpc == TRUE) && (peerMfpc == FALSE)) {
+ if ((selfMfpr == TRUE) && (peerMfpr == FALSE)) {
+ DBGLOG(RSN, ERROR, "PMF policy violation for case 4\n");
+ return STATUS_CODE_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
+ }
+
+ if (peerMfpr == TRUE) {
+ DBGLOG(RSN, ERROR, "PMF policy violation for case 7\n");
+ return STATUS_CODE_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
+ }
+ }
+
+ if ((selfMfpc == TRUE) && (peerMfpc == TRUE)) {
+ DBGLOG(RSN, ERROR, "PMF Connection\n");
+ prStaRec->rPmfCfg.fgApplyPmf = TRUE;
+ }
+
+ return STATUS_CODE_SUCCESSFUL;
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+* \brief This routine is called to generate TIMEOUT INTERVAL IE for association resp
+* Add Timeout interval IE (56) when PMF invalid association
+*
+*
+* \return (none)
+*/
+/*----------------------------------------------------------------------------*/
+VOID rsnPmfGenerateTimeoutIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo)
+{
+ IE_TIMEOUT_INTERVAL_T *prTimeout;
+ P_STA_RECORD_T prStaRec;
+
+ ASSERT(prAdapter);
+ ASSERT(prMsduInfo);
+
+ DBGLOG(RSN, INFO, "rsnPmfGenerateTimeoutIE\n");
+
+ prTimeout = (IE_TIMEOUT_INTERVAL_T *)
+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
+
+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
+
+ /* only when PMF connection, and association error code is 30 */
+ if ((rsnCheckBipKeyInstalled(prAdapter, prStaRec) == TRUE) &&
+ (prStaRec->u2StatusCode == STATUS_CODE_ASSOC_REJECTED_TEMPORARILY)) {
+
+ prTimeout->ucId = ELEM_ID_TIMEOUT_INTERVAL;
+ prTimeout->ucLength = ELEM_MAX_LEN_TIMEOUT_IE;
+ prTimeout->ucType = IE_TIMEOUT_INTERVAL_TYPE_ASSOC_COMEBACK;
+ prTimeout->u4Value = 1<<10;
+ prMsduInfo->u2FrameLength += IE_SIZE(prTimeout);
+ }
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to check the Sa query timeout.
+* check if total retry time is greater than 1000ms
+*
+* \retval 1: retry max timeout. 0: not timeout
+* \note
+* Called by: AAA module, Handle by Sa Query timeout
+*/
+/*----------------------------------------------------------------------------*/
+UINT_8 rsnApCheckSaQueryTimeout(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
+{
+ P_BSS_INFO_T prBssInfo;
+ UINT_32 now;
+
+ GET_CURRENT_SYSTIME(&now);
+
+ if (CHECK_FOR_TIMEOUT(now, prStaRec->rPmfCfg.u4SAQueryStart, TU_TO_MSEC(1000))) {
+ DBGLOG(RSN, INFO, "association SA Query timed out\n");
+
+ /* XXX PMF TODO how to report STA REC disconnect?? */
+ /* when SAQ retry count timeout, clear this STA */
+ prStaRec->rPmfCfg.ucSAQueryTimedOut = 1;
+ prStaRec->rPmfCfg.u2TransactionID = 0;
+ prStaRec->rPmfCfg.u4SAQueryCount = 0;
+ cnmTimerStopTimer(prAdapter, &prStaRec->rPmfCfg.rSAQueryTimer);
+
+ prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex);
+
+ /* refer to p2pRoleFsmRunEventRxDeauthentication*/
+ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {
+ if (bssRemoveClient(prAdapter, prBssInfo, prStaRec)) {
+ /* Indicate disconnect to Host. */
+ p2pFuncDisconnect(prAdapter, prBssInfo, prStaRec, FALSE, 0);
+ /* Deactive BSS if PWR is IDLE and no peer */
+ if (IS_NET_PWR_STATE_IDLE(prAdapter, prBssInfo->ucBssIndex) &&
+ (bssGetClientCount(prAdapter, prBssInfo) == 0)) {
+ /* All Peer disconnected !! Stop BSS now!! */
+ p2pFuncStopComplete(prAdapter, prBssInfo);
+ }
+ }
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to start the 802.11w sa query timer.
+* This routine is triggered every 201ms, and every time enter function, check max timeout
+*
+* \note
+* Called by: AAA module, Handle TX SAQ request
+*/
+/*----------------------------------------------------------------------------*/
+void rsnApStartSaQueryTimer(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN ULONG ulParamPtr)
+{
+ P_BSS_INFO_T prBssInfo;
+ P_MSDU_INFO_T prMsduInfo;
+ P_ACTION_SA_QUERY_FRAME prTxFrame;
+ UINT_16 u2PayloadLen;
+
+ ASSERT(prStaRec);
+
+ DBGLOG(RSN, INFO, "MFP: AP Start Sa Query\n");
+
+ prBssInfo = GET_BSS_INFO_BY_INDEX(prAdapter, prStaRec->ucBssIndex);
+
+ if (prStaRec->rPmfCfg.u4SAQueryCount > 0 && rsnApCheckSaQueryTimeout(prAdapter, prStaRec)) {
+ DBGLOG(RSN, INFO, "MFP: retry max timeout, u4SaQueryCount count =%lu\n",
+ prStaRec->rPmfCfg.u4SAQueryCount);
+ return;
+ }
+
+ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN);
+
+ if (!prMsduInfo)
+ return;
+
+ prTxFrame = (P_ACTION_SA_QUERY_FRAME)
+ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
+
+ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
+ if (rsnCheckBipKeyInstalled(prAdapter, prStaRec))
+ prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
+ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr);
+ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
+ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucOwnMacAddr);
+
+ prTxFrame->ucCategory = CATEGORY_SA_QUERY_ACTION;
+ prTxFrame->ucAction = ACTION_SA_QUERY_REQUEST;
+
+ if (prStaRec->rPmfCfg.u4SAQueryCount == 0)
+ GET_CURRENT_SYSTIME(&prStaRec->rPmfCfg.u4SAQueryStart);
+
+ /* if retry, transcation id ++ */
+ if (prStaRec->rPmfCfg.u4SAQueryCount) {
+ prStaRec->rPmfCfg.u2TransactionID++;
+ } else {
+ /* if first SAQ request, random pick transaction id */
+ prStaRec->rPmfCfg.u2TransactionID = (UINT_16) (kalRandomNumber() & 0xFFFF);
+ }
+
+ /* trnsform U16 to U8 array */
+ prTxFrame->ucTransId[0] = ((prStaRec->rPmfCfg.u2TransactionID & 0xff00) >> 8);
+ prTxFrame->ucTransId[1] = ((prStaRec->rPmfCfg.u2TransactionID & 0x00ff) >> 0);
+
+ prStaRec->rPmfCfg.u4SAQueryCount++;
+
+ u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN;
+
+ /* 4 <3> Update information of MSDU_INFO_T */
+ TX_SET_MMPDU(prAdapter,
+ prMsduInfo,
+ prStaRec->ucBssIndex,
+ prStaRec->ucIndex,
+ WLAN_MAC_MGMT_HEADER_LEN, WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, NULL, MSDU_RATE_MODE_AUTO);
+
+ if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) {
+ DBGLOG(RSN, INFO, "SAQ Set MSDU_OPT_PROTECTED_FRAME\n");
+ nicTxConfigPktOption(prMsduInfo, MSDU_OPT_PROTECTED_FRAME, TRUE);
+ }
+ /* 4 Enqueue the frame to send this action frame. */
+ nicTxEnqueueMsdu(prAdapter, prMsduInfo);
+
+ DBGLOG(RSN, INFO, "AP Set SA Query timer %lu (%d Tu)\n", prStaRec->rPmfCfg.u4SAQueryCount, 201);
+
+ cnmTimerStartTimer(prAdapter, &prStaRec->rPmfCfg.rSAQueryTimer, TU_TO_MSEC(201));
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to start the 802.11w TX SA query.
+*
+*
+* \note
+* Called by: AAA module, Handle Tx action frame request
+*/
+/*----------------------------------------------------------------------------*/
+void rsnApStartSaQuery(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
+{
+ ASSERT(prStaRec);
+
+ DBGLOG(RSN, INFO, "rsnApStartSaQuery\n");
+
+ if (prStaRec) {
+ cnmTimerStopTimer(prAdapter, &prStaRec->rPmfCfg.rSAQueryTimer);
+ cnmTimerInitTimer(prAdapter, &prStaRec->rPmfCfg.rSAQueryTimer,
+ (PFN_MGMT_TIMEOUT_FUNC)rsnApStartSaQueryTimer, (ULONG) prStaRec);
+ }
+
+ if (prStaRec->rPmfCfg.u4SAQueryCount == 0)
+ rsnApStartSaQueryTimer(prAdapter, prStaRec, (ULONG) NULL);
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to stop the 802.11w SA query.
+*
+*
+* \note
+* Called by: AAA module, stop TX SAQ if receive correct SAQ response
+*/
+/*----------------------------------------------------------------------------*/
+void rsnApStopSaQuery(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec)
+{
+ ASSERT(prStaRec);
+
+ cnmTimerStopTimer(prAdapter, &prStaRec->rPmfCfg.rSAQueryTimer);
+ prStaRec->rPmfCfg.u2TransactionID = 0;
+ prStaRec->rPmfCfg.u4SAQueryCount = 0;
+ prStaRec->rPmfCfg.ucSAQueryTimedOut = 0;
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to process the 802.11w sa query action frame.
+*
+*
+* \note
+* Called by: AAA module, Handle Rx action request
+*/
+/*----------------------------------------------------------------------------*/
+void rsnApSaQueryRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+ P_BSS_INFO_T prBssInfo;
+ P_MSDU_INFO_T prMsduInfo;
+ P_ACTION_SA_QUERY_FRAME prRxFrame = NULL;
+ UINT_16 u2PayloadLen;
+ P_STA_RECORD_T prStaRec;
+ P_ACTION_SA_QUERY_FRAME prTxFrame;
+
+ prBssInfo = prAdapter->prAisBssInfo;
+ ASSERT(prBssInfo);
+
+ if (!prSwRfb)
+ return;
+
+ prRxFrame = (P_ACTION_SA_QUERY_FRAME) prSwRfb->pvHeader;
+ if (!prRxFrame)
+ return;
+
+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+ if (!prStaRec) /* Todo:: for not AIS check */
+ return;
+
+ DBGLOG(RSN, INFO, "IEEE 802.11: Received SA Query Request from " MACSTR "\n", MAC2STR(prStaRec->aucMacAddr));
+
+ DBGLOG_MEM8(RSN, INFO, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
+
+ if (!rsnCheckBipKeyInstalled(prAdapter, prStaRec)) {
+ DBGLOG(RSN, INFO, "IEEE 802.11: Ignore SA Query Request non-PMF STA "
+ MACSTR "\n", MAC2STR(prStaRec->aucMacAddr));
+ return;
+ }
+
+ DBGLOG(RSN, INFO, "IEEE 802.11: Sending SA Query Response to " MACSTR "\n", MAC2STR(prStaRec->aucMacAddr));
+
+ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN);
+
+ if (!prMsduInfo)
+ return;
+
+ prTxFrame = (P_ACTION_SA_QUERY_FRAME)
+ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
+
+ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
+ if (rsnCheckBipKeyInstalled(prAdapter, prStaRec))
+ prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
+ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr);
+ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucBSSID);
+ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);
+
+ prTxFrame->ucCategory = CATEGORY_SA_QUERY_ACTION;
+ prTxFrame->ucAction = ACTION_SA_QUERY_RESPONSE;
+
+ kalMemCopy(prTxFrame->ucTransId, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
+
+ u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN;
+
+ /* 4 <3> Update information of MSDU_INFO_T */
+ TX_SET_MMPDU(prAdapter,
+ prMsduInfo,
+ prStaRec->ucBssIndex,
+ prStaRec->ucIndex,
+ WLAN_MAC_MGMT_HEADER_LEN, WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen, NULL, MSDU_RATE_MODE_AUTO);
+
+ if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) {
+ DBGLOG(RSN, INFO, "SAQ Set MSDU_OPT_PROTECTED_FRAME\n");
+ nicTxConfigPktOption(prMsduInfo, MSDU_OPT_PROTECTED_FRAME, TRUE);
+ }
+
+ /* 4 Enqueue the frame to send this action frame. */
+ nicTxEnqueueMsdu(prAdapter, prMsduInfo);
+
+}
+
+/*----------------------------------------------------------------------------*/
+/*!
+*
+* \brief This routine is called to process the 802.11w sa query action frame.
+*
+*
+* \note
+* Called by: AAA module, Handle Rx action request
+*/
+/*----------------------------------------------------------------------------*/
+void rsnApSaQueryAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
+{
+ P_ACTION_SA_QUERY_FRAME prRxFrame;
+ P_STA_RECORD_T prStaRec;
+ UINT_16 u2SwapTrID;
+
+ prRxFrame = (P_ACTION_SA_QUERY_FRAME) prSwRfb->pvHeader;
+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
+
+ if (prSwRfb->u2PacketLen < ACTION_SA_QUERY_TR_ID_LEN) {
+ DBGLOG(RSN, INFO, "IEEE 802.11: Too short SA Query Action frame (len=%lu)\n",
+ (unsigned long)prSwRfb->u2PacketLen);
+ return;
+ }
+
+ if (prRxFrame->ucAction == ACTION_SA_QUERY_REQUEST) {
+ rsnSaQueryRequest(prAdapter, prSwRfb);
+ return;
+ }
+
+ if (prRxFrame->ucAction != ACTION_SA_QUERY_RESPONSE) {
+ DBGLOG(RSN, INFO, "IEEE 802.11: Unexpected SA Query Action %d\n", prRxFrame->ucAction);
+ return;
+ }
+
+ DBGLOG(RSN, INFO, "IEEE 802.11: Received SA Query Response from " MACSTR "\n", MAC2STR(prStaRec->aucMacAddr));
+
+ DBGLOG_MEM8(RSN, INFO, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
+
+ /* MLME-SAQuery.confirm */
+ /* transform to network byte order */
+ u2SwapTrID = htons(prStaRec->rPmfCfg.u2TransactionID);
+ if (kalMemCmp((UINT_8 *)&u2SwapTrID, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN) == 0) {
+ DBGLOG(RSN, INFO, "Reply to SA Query received\n");
+ rsnApStopSaQuery(prAdapter, prStaRec);
+ } else {
+ DBGLOG(RSN, INFO, "IEEE 802.11: No matching SA Query transaction identifier found\n");
+ }
+
+}
+
+#endif /* CFG_SUPPORT_802_11W */
+
diff --git a/nic/nic_rx.c b/nic/nic_rx.c
index 5019455..914f272 100644
--- a/nic/nic_rx.c
+++ b/nic/nic_rx.c
@@ -3308,6 +3308,13 @@
prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection /* Use MFP */) {
/* MFP test plan 5.3.3.4 */
rsnSaQueryAction(prAdapter, prSwRfb);
+ } else if ((prBssInfo->eNetworkType == NETWORK_TYPE_P2P) &&
+ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) {
+ /* AP PMF */
+ if (rsnCheckBipKeyInstalled(prAdapter, prSwRfb->prStaRec)) {
+ /* MFP test plan 4.3.3.4 */
+ rsnApSaQueryAction(prAdapter, prSwRfb);
+ }
}
}
}
diff --git a/os/linux/gl_p2p.c b/os/linux/gl_p2p.c
index 76ea3d4..1f5d119 100644
--- a/os/linux/gl_p2p.c
+++ b/os/linux/gl_p2p.c
@@ -153,6 +153,7 @@
.get_key = mtk_p2p_cfg80211_get_key,
.del_key = mtk_p2p_cfg80211_del_key,
.set_default_key = mtk_p2p_cfg80211_set_default_key,
+ .set_default_mgmt_key = mtk_p2p_cfg80211_set_mgmt_key,
.join_ibss = mtk_p2p_cfg80211_join_ibss,
.leave_ibss = mtk_p2p_cfg80211_leave_ibss,
.set_tx_power = mtk_p2p_cfg80211_set_txpower,
diff --git a/os/linux/gl_p2p_cfg80211.c b/os/linux/gl_p2p_cfg80211.c
index b02e43c..a98d31a 100644
--- a/os/linux/gl_p2p_cfg80211.c
+++ b/os/linux/gl_p2p_cfg80211.c
@@ -588,10 +588,10 @@
#if DBG
DBGLOG(RSN, TRACE, "mtk_p2p_cfg80211_add_key\n");
if (mac_addr) {
- DBGLOG(RSN, TRACE,
+ DBGLOG(RSN, INFO,
"keyIdx = %d pairwise = %d mac = " MACSTR "\n", key_index, pairwise, MAC2STR(mac_addr));
} else {
- DBGLOG(RSN, TRACE, "keyIdx = %d pairwise = %d null mac\n", key_index, pairwise);
+ DBGLOG(RSN, INFO, "keyIdx = %d pairwise = %d null mac\n", key_index, pairwise);
}
DBGLOG(RSN, TRACE, "Cipher = %x\n", params->cipher);
DBGLOG_MEM8(RSN, TRACE, params->key, params->key_len);
@@ -790,6 +790,23 @@
return i4Rst;
}
+/*----------------------------------------------------------------------------*/
+/*!
+ * @brief This routine is responsible for setting the default mgmt key index
+ *
+ * @param
+ *
+ * @retval 0: successful
+ * others: failure
+ */
+/*----------------------------------------------------------------------------*/
+int mtk_p2p_cfg80211_set_mgmt_key(struct wiphy *wiphy, struct net_device *dev, u8 key_index)
+{
+ DBGLOG(RSN, INFO, "mtk_p2p_cfg80211_set_mgmt_key, kid:%d\n", key_index);
+
+ return 0;
+}
+
#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE
int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
const u8 *mac, struct station_info *sinfo)
diff --git a/os/linux/include/gl_p2p_ioctl.h b/os/linux/include/gl_p2p_ioctl.h
index a277288..414f383 100644
--- a/os/linux/include/gl_p2p_ioctl.h
+++ b/os/linux/include/gl_p2p_ioctl.h
@@ -405,6 +405,10 @@
int
mtk_p2p_cfg80211_set_default_key(struct wiphy *wiphy,
struct net_device *netdev, u8 key_index, bool unicast, bool multicast);
+
+int
+mtk_p2p_cfg80211_set_mgmt_key(struct wiphy *wiphy, struct net_device *dev, u8 key_index);
+
#if KERNEL_VERSION(3, 16, 0) <= CFG80211_VERSION_CODE
int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
const u8 *mac, struct station_info *sinfo);