wlan: Add PMF (802.11w) support for station mode
These changes add Protected Management Frames (802.11w) support for
the device in station mode.
Change-Id: I2cdc60c4a9ed3ab40303de11ca3b679a9fe1d455
CRs-Fixed: 452422, 452831, 455139, 450564, 452558
diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h
index 932a388..901217b 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -81,6 +81,9 @@
eCSR_AUTH_TYPE_CCKM_WPA,
eCSR_AUTH_TYPE_CCKM_RSN,
#endif /* FEATURE_WLAN_CCX */
+#ifdef WLAN_FEATURE_11W
+ eCSR_AUTH_TYPE_RSN_PSK_SHA256,
+#endif
eCSR_NUM_OF_SUPPORT_AUTH_TYPE,
eCSR_AUTH_TYPE_FAILED = 0xff,
eCSR_AUTH_TYPE_UNKNOWN = eCSR_AUTH_TYPE_FAILED,
@@ -459,6 +462,9 @@
eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS, //Disaconnect all the clients
eCSR_ROAM_SEND_P2P_STOP_BSS, //Stopbss triggered from SME due to different
// beacon interval
+#ifdef WLAN_FEATURE_11W
+ eCSR_ROAM_UNPROT_MGMT_FRAME_IND,
+#endif
}eRoamCmdStatus;
@@ -704,7 +710,8 @@
}eCsrWEPStaticKeyID;
-#define CSR_MAX_NUM_KEY (eCSR_SECURITY_WEP_STATIC_KEY_ID_MAX + 1)
+// Two extra key indicies are used for the IGTK (which is used by BIP)
+#define CSR_MAX_NUM_KEY (eCSR_SECURITY_WEP_STATIC_KEY_ID_MAX + 2 + 1)
typedef enum
{
@@ -825,6 +832,13 @@
//This field is for output only, not for input
eCsrEncryptionType negotiatedMCEncryptionType;
+#ifdef WLAN_FEATURE_11W
+ // Management Frame Protection
+ tANI_BOOLEAN MFPEnabled;
+ tANI_U8 MFPRequired;
+ tANI_U8 MFPCapable;
+#endif
+
tCsrKeys Keys;
eCsrCBChoice CBMode; //up, down or auto
tCsrChannelInfo ChannelInfo;
diff --git a/CORE/SME/inc/csrSupport.h b/CORE/SME/inc/csrSupport.h
index a28f33d..45a0586 100644
--- a/CORE/SME/inc/csrSupport.h
+++ b/CORE/SME/inc/csrSupport.h
@@ -40,15 +40,13 @@
*/
/** ------------------------------------------------------------------------- *
- ------------------------------------------------------------------------- *
-
\file csrSupport.h
-
+
Exports and types for the Common Scan and Roaming supporting interfaces.
Copyright (C) 2006 Airgo Networks, Incorporated
-
+
========================================================================== */
#ifndef CSR_SUPPORT_H__
#define CSR_SUPPORT_H__
@@ -593,7 +591,9 @@
tANI_U16 NoPairwise:1;
tANI_U16 PTKSAReplayCounter:2;
tANI_U16 GTKSAReplayCounter:2;
- tANI_U16 Reserved:10;
+ tANI_U16 MFPRequired:1;
+ tANI_U16 MFPCapable:1;
+ tANI_U16 Reserved:8;
} __ani_attr_packed tCsrRSNCapabilities;
typedef __ani_attr_pre_packed struct tagCsrRSNPMKIe
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index 71f1da8..c1555ac 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -150,6 +150,9 @@
n = AUTH_WPA2_EAP;
break;
case eCSR_AUTH_TYPE_RSN_PSK:
+#ifdef WLAN_FEATURE_11W
+ case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
+#endif
n = AUTH_WPA2_PSK;
break;
#ifdef FEATURE_WLAN_WAPI
@@ -4436,6 +4439,10 @@
(eCSR_AUTH_TYPE_WAPI_WAI_PSK == authType) ||
(eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE == authType)
#endif /* FEATURE_WLAN_WAPI */
+#ifdef WLAN_FEATURE_11W
+ ||
+ (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == authType)
+#endif /* FEATURE_WLAN_WAPI */
)
{
if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesLocal))) )
@@ -4451,6 +4458,9 @@
(eCSR_AUTH_TYPE_FT_RSN == authType) ||
(eCSR_AUTH_TYPE_FT_RSN_PSK == authType) ||
#endif /* WLAN_FEATURE_VOWIFI_11R */
+#if defined WLAN_FEATURE_11W
+ (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == authType) ||
+#endif
(eCSR_AUTH_TYPE_RSN_PSK == authType))
{
if(pIesLocal->RSN.present)
@@ -5582,6 +5592,11 @@
pDstProfile->negotiatedUCEncryptionType = pSrcProfile->negotiatedUCEncryptionType;
pDstProfile->negotiatedMCEncryptionType = pSrcProfile->negotiatedMCEncryptionType;
pDstProfile->negotiatedAuthType = pSrcProfile->negotiatedAuthType;
+#ifdef WLAN_FEATURE_11W
+ pDstProfile->MFPEnabled = pSrcProfile->MFPEnabled;
+ pDstProfile->MFPRequired = pSrcProfile->MFPRequired;
+ pDstProfile->MFPCapable = pSrcProfile->MFPCapable;
+#endif
pDstProfile->BSSType = pSrcProfile->BSSType;
pDstProfile->phyMode = pSrcProfile->phyMode;
pDstProfile->csrPersona = pSrcProfile->csrPersona;
@@ -6563,6 +6578,9 @@
|| (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA)
|| (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK)
|| (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN)
+#ifdef WLAN_FEATURE_11W
+ || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256)
+#endif
|| (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK))))
&& (pMac->roam.configParam.isCcxIniFeatureEnabled))
{
@@ -7829,16 +7847,15 @@
#ifdef WLAN_FEATURE_11W
//Check for 11w BIP
- else if ( eCSR_ENCRYPT_TYPE_AES_CMAC == pSetKey->encType )
+ else if (eCSR_ENCRYPT_TYPE_AES_CMAC == pSetKey->encType)
{
- tANI_U16 count = 0;
- if ( pSetKey->keyLength < CSR_AES_KEY_LEN )
+ if (pSetKey->keyLength < CSR_AES_KEY_LEN)
{
- smsLog( pMac, LOGW, "Invalid AES/CCMP keylength [= %d] in SetContext call", pSetKey->keyLength );
+ smsLog(pMac, LOGW, "Invalid AES/CCMP keylength [= %d] in SetContext call", pSetKey->keyLength);
break;
}
pCommand->u.setKeyCmd.keyLength = CSR_AES_KEY_LEN;
- palCopyMemory( pMac->hHdd, pCommand->u.setKeyCmd.Key, pSetKey->Key, CSR_AES_KEY_LEN );
+ palCopyMemory(pMac->hHdd, pCommand->u.setKeyCmd.Key, pSetKey->Key, CSR_AES_KEY_LEN);
}
#endif
status = eHAL_STATUS_SUCCESS;
@@ -11878,6 +11895,19 @@
dwTmp = pal_cpu_to_be32( csrTranslateEncryptTypeToEdType( pProfile->negotiatedMCEncryptionType) );
palCopyMemory( pMac->hHdd, pBuf, &dwTmp, sizeof(tANI_U32) );
pBuf += sizeof(tANI_U32);
+#ifdef WLAN_FEATURE_11W
+ //MgmtEncryption
+ if (pProfile->MFPEnabled)
+ {
+ dwTmp = pal_cpu_to_be32(eSIR_ED_AES_128_CMAC);
+ }
+ else
+ {
+ dwTmp = pal_cpu_to_be32(eSIR_ED_NONE);
+ }
+ palCopyMemory(pMac->hHdd, pBuf, &dwTmp, sizeof(tANI_U32));
+ pBuf += sizeof(tANI_U32);
+#endif
#ifdef WLAN_FEATURE_VOWIFI_11R
pProfile->MDID.mdiePresent = pBssDescription->mdiePresent;
if (csrIsProfile11r( pProfile )
@@ -11912,6 +11942,9 @@
|| (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA)
|| (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK)
|| (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN)
+#ifdef WLAN_FEATURE_11W
+ || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256)
+#endif
|| (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK))))
&& (pMac->roam.configParam.isCcxIniFeatureEnabled))
{
@@ -11945,6 +11978,9 @@
|| (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA)
|| (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK)
|| (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN)
+#ifdef WLAN_FEATURE_11W
+ || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256)
+#endif
|| (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK))))
&& (pMac->roam.configParam.isCcxIniFeatureEnabled))
{
diff --git a/CORE/SME/src/csr/csrUtil.c b/CORE/SME/src/csr/csrUtil.c
index 6d9e6a9..25bff95 100644
--- a/CORE/SME/src/csr/csrUtil.c
+++ b/CORE/SME/src/csr/csrUtil.c
@@ -2753,6 +2753,9 @@
#ifdef FEATURE_WLAN_CCX
case eCSR_AUTH_TYPE_CCKM_RSN:
#endif
+#ifdef WLAN_FEATURE_11W
+ case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
+#endif
fRSNProfile = TRUE;
break;
@@ -3410,7 +3413,7 @@
{
#ifdef WLAN_FEATURE_11W
return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[01], Oui ) ||
- csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[05], Oui ));
+ csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[06], Oui ));
#else
return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[01], Oui ) );
#endif
@@ -3427,6 +3430,15 @@
#endif
}
+#ifdef WLAN_FEATURE_11W
+static tANI_BOOLEAN csrIsAuthRSNPskSha256( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE],
+ tANI_U8 cAllSuites,
+ tANI_U8 Oui[] )
+{
+ return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[06], Oui ) );
+}
+#endif
+
static tANI_BOOLEAN csrIsAuthWpa( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_WPA_OUI_SIZE],
tANI_U8 cAllSuites,
tANI_U8 Oui[] )
@@ -3636,6 +3648,13 @@
if (eCSR_AUTH_TYPE_RSN_PSK == pAuthType->authType[i])
negAuthType = eCSR_AUTH_TYPE_RSN_PSK;
}
+#ifdef WLAN_FEATURE_11W
+ if ((negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsAuthRSNPskSha256( pMac, AuthSuites, cAuthSuites, Authentication ) )
+ {
+ if (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == pAuthType->authType[i])
+ negAuthType = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
+ }
+#endif
// The 1st auth type in the APs RSN IE, to match stations connecting
// profiles auth type will cause us to exit this loop
@@ -3676,9 +3695,12 @@
Capabilities->PreAuthSupported = (pRSNIe->RSN_Cap[0] >> 0) & 0x1 ; // Bit 0 PreAuthentication
Capabilities->NoPairwise = (pRSNIe->RSN_Cap[0] >> 1) & 0x1 ; // Bit 1 No Pairwise
Capabilities->PTKSAReplayCounter = (pRSNIe->RSN_Cap[0] >> 2) & 0x3 ; // Bit 2, 3 PTKSA Replay Counter
- Capabilities->GTKSAReplayCounter = (pRSNIe->RSN_Cap[0] >> 4) & 0x3 ; // Bit 4,5 GTKSA Replay Counter
- Capabilities->Reserved = (pRSNIe->RSN_Cap[0] >> 6) & 0x3 ; // remaining reserved
- Capabilities->Reserved = (Capabilities->Reserved >> 2) | (pRSNIe->RSN_Cap[1] & 0xff) ; // remaining reserved
+ Capabilities->GTKSAReplayCounter = (pRSNIe->RSN_Cap[0] >> 4) & 0x3 ; // Bit 4, 5 GTKSA Replay Counter
+#ifdef WLAN_FEATURE_11W
+ Capabilities->MFPRequired = (pRSNIe->RSN_Cap[0] >> 6) & 0x1 ; // Bit 6 MFPR
+ Capabilities->MFPCapable = (pRSNIe->RSN_Cap[0] >> 7) & 0x1 ; // Bit 7 MFPC
+#endif
+ Capabilities->Reserved = pRSNIe->RSN_Cap[1] & 0xff ; // remaining reserved
}
}
return( fAcceptableCyphers );
@@ -3798,7 +3820,12 @@
// !!REVIEW - What should STA put in RSN capabilities, currently
// just putting back APs capabilities
// For one, we shouldn't EVER be sending out "pre-auth supported". It is an AP only capability
+ // For another, we should use the Management Frame Protection values given by the supplicant
RSNCapabilities.PreAuthSupported = 0;
+#ifdef WLAN_FEATURE_11W
+ RSNCapabilities.MFPRequired = pProfile->MFPRequired;
+ RSNCapabilities.MFPCapable = pProfile->MFPCapable;
+#endif
*(tANI_U16 *)( &pAuthSuite->AuthOui[ 1 ] ) = *((tANI_U16 *)(&RSNCapabilities));
pPMK = (tCsrRSNPMKIe *)( ((tANI_U8 *)(&pAuthSuite->AuthOui[ 1 ])) + sizeof(tANI_U16) );
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index f19da09..d2d10ff 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -118,6 +118,11 @@
tANI_BOOLEAN csrIsScanAllowed(tpAniSirGlobal pMac);
#endif
+#ifdef WLAN_FEATURE_11W
+eHalStatus sme_UnprotectedMgmtFrmInd( tHalHandle hHal,
+ tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm );
+#endif
+
//Internal SME APIs
eHalStatus sme_AcquireGlobalLock( tSmeStruct *psSme)
{
@@ -1400,6 +1405,34 @@
#endif // WLAN_FEATURE_PACKET_FILTERING
+#ifdef WLAN_FEATURE_11W
+/*------------------------------------------------------------------
+ *
+ * Handle the unprotected management frame indication from LIM and
+ * forward it to HDD.
+ *
+ *------------------------------------------------------------------*/
+
+eHalStatus sme_UnprotectedMgmtFrmInd( tHalHandle hHal,
+ tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm)
+{
+ tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tCsrRoamInfo pRoamInfo = {0};
+ tANI_U32 SessionId = pSmeMgmtFrm->sessionId;
+
+ pRoamInfo.nFrameLength = pSmeMgmtFrm->frameLen;
+ pRoamInfo.pbFrames = pSmeMgmtFrm->frameBuf;
+ pRoamInfo.frameType = pSmeMgmtFrm->frameType;
+
+ /* forward the mgmt frame to HDD */
+ csrRoamCallCallback(pMac, SessionId, &pRoamInfo, 0, eCSR_ROAM_UNPROT_MGMT_FRAME_IND, 0);
+
+ return status;
+}
+#endif
+
+
/*--------------------------------------------------------------------------
\brief sme_ProcessMsg() - The main message processor for SME.
@@ -1708,6 +1741,20 @@
}
#endif
+#ifdef WLAN_FEATURE_11W
+ case eWNI_SME_UNPROT_MGMT_FRM_IND:
+ if (pMsg->bodyptr)
+ {
+ sme_UnprotectedMgmtFrmInd(pMac, pMsg->bodyptr);
+ vos_mem_free(pMsg->bodyptr);
+ }
+ else
+ {
+ smsLog(pMac, LOGE, "Empty rsp message for meas (eWNI_SME_UNPROT_MGMT_FRM_IND), nothing to process");
+ }
+ break;
+#endif
+
default:
if ( ( pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN )