wlan:pmf:Block connection to non-pmfap incase of PMF connection

this patch will fix block the connection in following condition,
1) if STA has PMFCapable and PMFRequired flags set and the AP to which we
are going to connect is not capable of PMF

2) if STA has PMFCapable and PMFRequired flags not set and the AP
to which we are going to make a connection has PMF mandatory.

3) if STA has optional PMF connection but supplicant asked us to make
PMF connection, in that case we will not make connection to any non-PMF
AP even though it is legitimate to make non-pmf connection with that
AP

Change-Id: Id680b208f7e7a2f604bd17fde9097aa92a47a74e
CRs-Fixed: 664205
diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h
index f50ef68..23f68da 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -377,6 +377,12 @@
     tCsrMobilityDomainInfo MDID;
 #endif
     tANI_BOOLEAN p2pResult;
+#ifdef WLAN_FEATURE_11W
+    // Management Frame Protection
+    tANI_BOOLEAN MFPEnabled;
+    tANI_U8 MFPRequired;
+    tANI_U8 MFPCapable;
+#endif
 }tCsrScanResultFilter;
 
 
diff --git a/CORE/SME/inc/csrSupport.h b/CORE/SME/inc/csrSupport.h
index 11541fe..314feae 100644
--- a/CORE/SME/inc/csrSupport.h
+++ b/CORE/SME/inc/csrSupport.h
@@ -764,7 +764,12 @@
 tANI_BOOLEAN csrRatesIsDot11Rate11aSupportedRate( tANI_U8 dot11Rate );
 tAniEdType csrTranslateEncryptTypeToEdType( eCsrEncryptionType EncryptType ); 
 //pIes shall contain IEs from pSirBssDesc. It shall be returned from function csrGetParsedBssDescriptionIEs 
-tANI_BOOLEAN csrIsSecurityMatch( tHalHandle hHal, tCsrAuthList *authType, tCsrEncryptionList *pUCEncryptionType, tCsrEncryptionList *pMCEncryptionType,
+tANI_BOOLEAN csrIsSecurityMatch( tHalHandle hHal, tCsrAuthList *authType,
+                                 tCsrEncryptionList *pUCEncryptionType,
+                                 tCsrEncryptionList *pMCEncryptionType,
+                                 tANI_BOOLEAN *pMFPEnabled,
+                                 tANI_U8 *pMFPRequired,
+                                 tANI_U8 *pMFPCapable,
                                  tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes, 
                                  eCsrAuthType *negotiatedAuthtype, eCsrEncryptionType *negotiatedUCCipher, eCsrEncryptionType *negotiatedMCCipher );
 tANI_BOOLEAN csrIsBSSTypeMatch(eCsrRoamBssType bssType1, eCsrRoamBssType bssType2);
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index a4b1fa4..4730c64 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -8997,7 +8997,14 @@
             pScanFilter->MDID.mobilityDomain = pProfile->MDID.mobilityDomain;
         }
 #endif
-    
+
+#ifdef WLAN_FEATURE_11W
+        // Management Frame Protection
+        pScanFilter->MFPEnabled = pProfile->MFPEnabled;
+        pScanFilter->MFPRequired = pProfile->MFPRequired;
+        pScanFilter->MFPCapable = pProfile->MFPCapable;
+#endif
+
     }while(0);
     
     if(!HAL_STATUS_SUCCESS(status))
diff --git a/CORE/SME/src/csr/csrApiScan.c b/CORE/SME/src/csr/csrApiScan.c
index d66c44e..d4f8bf8 100644
--- a/CORE/SME/src/csr/csrApiScan.c
+++ b/CORE/SME/src/csr/csrApiScan.c
@@ -2129,8 +2129,14 @@
                     }
                     else
                     {
-                        fMatch = csrIsSecurityMatch( pMac, &pFilter->authType, &pFilter->EncryptionType, &pFilter->mcEncryptionType,
-                                 &pBssDesc->Result.BssDescriptor, pIes, NULL, NULL, NULL );
+                        fMatch = csrIsSecurityMatch(pMac, &pFilter->authType,
+                                                &pFilter->EncryptionType,
+                                                &pFilter->mcEncryptionType,
+                                                &pFilter->MFPEnabled,
+                                                &pFilter->MFPRequired,
+                                                &pFilter->MFPCapable,
+                                                &pBssDesc->Result.BssDescriptor,
+                                                pIes, NULL, NULL, NULL );
                     }
                     if ((pBssDesc->Result.pvIes == NULL) && pIes)
                          vos_mem_free(pIes);
diff --git a/CORE/SME/src/csr/csrNeighborRoam.c b/CORE/SME/src/csr/csrNeighborRoam.c
index 9aaa89d..91fd417 100644
--- a/CORE/SME/src/csr/csrNeighborRoam.c
+++ b/CORE/SME/src/csr/csrNeighborRoam.c
@@ -3239,8 +3239,19 @@
                     eANI_BOOLEAN_TRUE );
             if(TRUE == fMatch)
             {
-                fMatch = csrIsSecurityMatch( pMac, &authType, &uCEncryptionType,
-                            &mCEncryptionType, pBssDesc, pIes, NULL, NULL, NULL );
+                /*
+                 * for now we are sending NULL for all PMF related filter
+                 * parameters during roam to the neighbor AP because
+                 * so far 80211W spec doesn't specify anything about
+                 * roaming scenario.
+                 *
+                 * Once roaming scenario is defined, we should re-visit
+                 * this section and remove this comment.
+                 */
+                fMatch = csrIsSecurityMatch(pMac, &authType, &uCEncryptionType,
+                                            &mCEncryptionType,
+                                            NULL, NULL, NULL,
+                                            pBssDesc, pIes, NULL, NULL, NULL);
                 return (fMatch);
             }
             else
diff --git a/CORE/SME/src/csr/csrUtil.c b/CORE/SME/src/csr/csrUtil.c
index 30e91ab..7b8a3cb 100644
--- a/CORE/SME/src/csr/csrUtil.c
+++ b/CORE/SME/src/csr/csrUtil.c
@@ -3720,15 +3720,115 @@
     return( fAcceptableCyphers );
 }
 
+#ifdef WLAN_FEATURE_11W
+/* ---------------------------------------------------------------------------
+    \fn csrIsPMFCapabilitiesInRSNMatch
 
-tANI_BOOLEAN csrIsRSNMatch( tHalHandle hHal, tCsrAuthList *pAuthType, eCsrEncryptionType enType, tCsrEncryptionList *pEnMcType, 
-                            tDot11fBeaconIEs *pIes, eCsrAuthType *pNegotiatedAuthType, eCsrEncryptionType *pNegotiatedMCCipher )
+    \brief this function is to match our current capabilities with the AP
+           to which we are expecting make the connection.
+
+    \param hHal               - HAL Pointer
+           pFilterMFPEnabled  - given by supplicant to us to specify what kind
+                                of connection supplicant is expecting to make
+                                if it is enabled then make PMF connection.
+                                if it is disabled then make normal connection.
+           pFilterMFPRequired - given by supplicant based on our configuration
+                                if it is 1 then we will require mandatory
+                                PMF connection and if it is 0 then we PMF
+                                connection is optional.
+           pFilterMFPCapable  - given by supplicant based on our configuration
+                                if it 1 then we are PMF capable and if it 0
+                                then we are not PMF capable.
+           pRSNIe             - RSNIe from Beacon/probe response of
+                                neighbor AP against which we will compare
+                                our capabilities.
+
+    \return tANI_BOOLEAN      - if our PMF capabilities matches with AP then we
+                                will return true to indicate that we are good
+                                to make connection with it. Else we will return
+                                false.
+  -------------------------------------------------------------------------------*/
+static tANI_BOOLEAN
+csrIsPMFCapabilitiesInRSNMatch( tHalHandle hHal,
+                                tANI_BOOLEAN *pFilterMFPEnabled,
+                                tANI_U8 *pFilterMFPRequired,
+                                tANI_U8 *pFilterMFPCapable,
+                                tDot11fIERSN *pRSNIe)
+{
+    tANI_U8 apProfileMFPCapable  = 0;
+    tANI_U8 apProfileMFPRequired = 0;
+    if (pRSNIe && pFilterMFPEnabled && pFilterMFPCapable && pFilterMFPRequired)
+    {
+       /* Extracting MFPCapable bit from RSN Ie */
+       apProfileMFPCapable  = (pRSNIe->RSN_Cap[0] >> 7) & 0x1;
+       apProfileMFPRequired = (pRSNIe->RSN_Cap[0] >> 6) & 0x1;
+       if (*pFilterMFPEnabled && *pFilterMFPCapable && *pFilterMFPRequired
+           && (apProfileMFPCapable == 0))
+       {
+           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+                     "AP is not capable to make PMF connection");
+           return VOS_FALSE;
+       }
+       else if (*pFilterMFPEnabled && *pFilterMFPCapable &&
+                !(*pFilterMFPRequired) && (apProfileMFPCapable == 0))
+       {
+           /*
+            * This is tricky, because supplicant asked us to make mandatory
+            * PMF connection eventhough PMF connection is optional here.
+            * so if AP is not capable of PMF then drop it. Don't try to
+            * connect with it.
+            */
+           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+           "we need PMF connection & AP isn't capable to make PMF connection");
+           return VOS_FALSE;
+       }
+       else if (!(*pFilterMFPCapable) &&
+                apProfileMFPCapable && apProfileMFPRequired)
+       {
+           /*
+            * In this case, AP with whom we trying to connect requires
+            * mandatory PMF connections and we are not capable so this AP
+            * is not good choice to connect
+            */
+           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+           "AP needs PMF connection and we are not capable of pmf connection");
+           return VOS_FALSE;
+       }
+       else if (!(*pFilterMFPEnabled) && *pFilterMFPCapable &&
+                (apProfileMFPCapable == 1))
+       {
+           VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+           "we don't need PMF connection eventhough both parties are capable");
+           return VOS_FALSE;
+       }
+    }
+    return VOS_TRUE;
+}
+#endif
+
+tANI_BOOLEAN csrIsRSNMatch( tHalHandle hHal, tCsrAuthList *pAuthType,
+                            eCsrEncryptionType enType,
+                            tCsrEncryptionList *pEnMcType,
+                            tANI_BOOLEAN *pMFPEnabled, tANI_U8 *pMFPRequired,
+                            tANI_U8 *pMFPCapable,
+                            tDot11fBeaconIEs *pIes,
+                            eCsrAuthType *pNegotiatedAuthType,
+                            eCsrEncryptionType *pNegotiatedMCCipher )
 {
     tANI_BOOLEAN fRSNMatch = FALSE;
 
         // See if the cyphers in the Bss description match with the settings in the profile.
     fRSNMatch = csrGetRSNInformation( hHal, pAuthType, enType, pEnMcType, &pIes->RSN, NULL, NULL, NULL, NULL, 
                                       pNegotiatedAuthType, pNegotiatedMCCipher );
+#ifdef WLAN_FEATURE_11W
+    /* If all the filter matches then finally checks for PMF capabilities */
+    if (fRSNMatch)
+    {
+        fRSNMatch = csrIsPMFCapabilitiesInRSNMatch( hHal, pMFPEnabled,
+                                                    pMFPRequired, pMFPCapable,
+                                                    &pIes->RSN);
+    }
+#endif
 
     return( fRSNMatch );
 }
@@ -4823,9 +4923,16 @@
 
 
 //pIes shall contain IEs from pSirBssDesc. It shall be returned from function csrGetParsedBssDescriptionIEs
-tANI_BOOLEAN csrIsSecurityMatch( tHalHandle hHal, tCsrAuthList *authType, tCsrEncryptionList *pUCEncryptionType, tCsrEncryptionList *pMCEncryptionType,
-                                 tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes, 
-                                 eCsrAuthType *negotiatedAuthtype, eCsrEncryptionType *negotiatedUCCipher, eCsrEncryptionType *negotiatedMCCipher )
+tANI_BOOLEAN csrIsSecurityMatch( tHalHandle hHal, tCsrAuthList *authType,
+                                 tCsrEncryptionList *pUCEncryptionType,
+                                 tCsrEncryptionList *pMCEncryptionType,
+                                 tANI_BOOLEAN *pMFPEnabled,
+                                 tANI_U8 *pMFPRequired, tANI_U8 *pMFPCapable,
+                                 tSirBssDescription *pSirBssDesc,
+                                 tDot11fBeaconIEs *pIes,
+                                 eCsrAuthType *negotiatedAuthtype,
+                                 eCsrEncryptionType *negotiatedUCCipher,
+                                 eCsrEncryptionType *negotiatedMCCipher )
 {
     tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
     tANI_BOOLEAN fMatch = FALSE;
@@ -4908,7 +5015,10 @@
                     if(pIes)
                     {
                         // First check if there is a RSN match
-                        fMatch = csrIsRSNMatch( pMac, authType, ucCipher, pMCEncryptionType, pIes, &negAuthType, &mcCipher );
+                        fMatch = csrIsRSNMatch( pMac, authType, ucCipher,
+                                                pMCEncryptionType, pMFPEnabled,
+                                                pMFPRequired, pMFPCapable,
+                                                pIes, &negAuthType, &mcCipher );
                         if( !fMatch )
                         {
                             // If not RSN, then check if there is a WPA match
@@ -4947,12 +5057,19 @@
                 {
                     //Check AES first
                     ucCipher = eCSR_ENCRYPT_TYPE_AES;
-                    fMatchAny = csrIsRSNMatch( hHal, authType, ucCipher, pMCEncryptionType, pIes, &negAuthType, &mcCipher );
+                    fMatchAny = csrIsRSNMatch( hHal, authType, ucCipher,
+                                               pMCEncryptionType, pMFPEnabled,
+                                               pMFPRequired, pMFPCapable, pIes,
+                                               &negAuthType, &mcCipher );
                     if(!fMatchAny)
                     {
                         //Check TKIP
                         ucCipher = eCSR_ENCRYPT_TYPE_TKIP;
-                        fMatchAny = csrIsRSNMatch( hHal, authType, ucCipher, pMCEncryptionType, pIes, &negAuthType, &mcCipher );
+                        fMatchAny = csrIsRSNMatch( hHal, authType, ucCipher,
+                                                   pMCEncryptionType,
+                                                   pMFPEnabled, pMFPRequired,
+                                                   pMFPCapable, pIes,
+                                                   &negAuthType, &mcCipher );
                     }
 #ifdef FEATURE_WLAN_WAPI
                     if(!fMatchAny)
@@ -5556,8 +5673,14 @@
 #endif
         if ( !csrIsPhyModeMatch( pMac, pFilter->phyMode, pBssDesc, NULL, NULL, pIes ) ) break;
         if ( (!pFilter->bWPSAssociation) && (!pFilter->bOSENAssociation) &&
-             !csrIsSecurityMatch( pMac, &pFilter->authType, &pFilter->EncryptionType, &pFilter->mcEncryptionType,
-                                 pBssDesc, pIes, pNegAuth, pNegUc, pNegMc ) ) break;
+             !csrIsSecurityMatch( pMac, &pFilter->authType,
+                                  &pFilter->EncryptionType,
+                                  &pFilter->mcEncryptionType,
+                                  &pFilter->MFPEnabled,
+                                  &pFilter->MFPRequired,
+                                  &pFilter->MFPCapable,
+                                  pBssDesc, pIes, pNegAuth,
+                                  pNegUc, pNegMc ) ) break;
         if ( !csrIsCapabilitiesMatch( pMac, pFilter->BSSType, pBssDesc ) ) break;
         if ( !csrIsRateSetMatch( pMac, &pIes->SuppRates, &pIes->ExtSuppRates ) ) break;
         //Tush-QoS: validate first if asked for APSD or WMM association
@@ -5614,7 +5737,9 @@
     authList.numEntries = 1;
     authList.authType[0] = pProfile->AuthType;
 
-    return( csrIsSecurityMatch( pMac, &authList, &ucEncryptionList, &mcEncryptionList, pBssDesc, pIes, NULL, NULL, NULL ));
+    return( csrIsSecurityMatch( pMac, &authList, &ucEncryptionList,
+                                &mcEncryptionList, NULL, NULL, NULL,
+                                pBssDesc, pIes, NULL, NULL, NULL ));
 
 }