qcacld-3.0: Invalid pmkid in the FT-EAP disconnection case
During FT-EAP roaming after session timeout if the FTIE received in the EAPOL of full EAP is improper, the supplicant would disconnect the AP with the reason FTIE mismatch. During this disconnection supplicant flushes all the existing PMK cache entries and eventually the framework would add these cache entries again (apparently, the current entry would be with the older PMK). On this addition to the driver, there is no connected profile and thus no MDID is associated to this PMKSA entry(AP1-PMK1). Further, on the fresh (Full EAP) connection to the AP2 with the same MDID, a new cache entry gets added and thus MDID from the connected profile gets associated with the PMKSA cache entry. At this point of time, there are two PMKSA cache entries (AP1-PMK1 without MDID and AP2-PMK2 with MDID). Adding further, if the incorrect PMK (without MDID / stale entry) i.e. PMK1 is given to the firmware on the RSO command for the specific BSSID (here AP1) during roam, further roams shall be calculated with this PMK1 and result in to the invalid pmkid issue. Thus, avoid this situation by removing that stale PMKSA entry in the driver and this entry can be deleted only when it is associated with the MDID. Driver on the new pmksa addition shall check for the matching pmksa cache entry with the MDID and delete the earlier ones. To associate the MDID, this commit checks for the same from the scan entry of the BSSID, if there is no connected profile for the same (this happened when the framework has added the cache entry when in the disconnected state). Change-Id: If81d66059173dda8d7a2940ca10dc96ef16e125c CRs-Fixed: 2972115
This commit is contained in:

committed by
Madan Koyyalamudi

parent
6cf44035f3
commit
0ec902c074
@@ -3953,11 +3953,12 @@ void cm_update_pmk_cache_ft(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
|
||||
}
|
||||
|
||||
/*
|
||||
* In FT connection fetch the MDID from Session and send it to crypto
|
||||
* so that it will update the crypto PMKSA table with the MDID for the
|
||||
* matching BSSID or SSID PMKSA entry. And delete the old/stale PMK
|
||||
* cache entries for the same mobility domain as of the newly added
|
||||
* entry to avoid multiple PMK cache entries for the same MDID.
|
||||
* In FT connection fetch the MDID from Session or scan result whichever
|
||||
* and send it to crypto so that it will update the crypto PMKSA table
|
||||
* with the MDID for the matching BSSID or SSID PMKSA entry. And delete
|
||||
* the old/stale PMK cache entries for the same mobility domain as of
|
||||
* the newly added entry to avoid multiple PMK cache entries for the
|
||||
* same MDID.
|
||||
*/
|
||||
wlan_vdev_get_bss_peer_mac(vdev, &pmksa.bssid);
|
||||
wlan_vdev_mlme_get_ssid(vdev, pmksa.ssid, &pmksa.ssid_len);
|
||||
@@ -3968,7 +3969,7 @@ void cm_update_pmk_cache_ft(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
|
||||
if (src_cfg.bool_value) {
|
||||
pmksa.mdid.mdie_present = 1;
|
||||
pmksa.mdid.mobility_domain = src_cfg.uint_value;
|
||||
mlme_debug("copied the MDID from session to PMKSA");
|
||||
mlme_debug("copied the MDID to PMKSA");
|
||||
|
||||
status = wlan_crypto_update_pmk_cache_ft(vdev, &pmksa);
|
||||
if (status == QDF_STATUS_SUCCESS)
|
||||
|
@@ -19699,10 +19699,12 @@ static QDF_STATUS wlan_hdd_set_pmksa_cache(struct hdd_adapter *adapter,
|
||||
qdf_mem_free(pmksa);
|
||||
}
|
||||
|
||||
if (result == QDF_STATUS_SUCCESS && pmk_cache->pmk_len)
|
||||
if (result == QDF_STATUS_SUCCESS && pmk_cache->pmk_len) {
|
||||
sme_roam_set_psk_pmk(mac_handle, adapter->vdev_id,
|
||||
pmk_cache->pmk, pmk_cache->pmk_len,
|
||||
false);
|
||||
sme_set_pmk_cache_ft(mac_handle, adapter->vdev_id, pmk_cache);
|
||||
}
|
||||
hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
|
||||
|
||||
return result;
|
||||
|
@@ -597,6 +597,18 @@ void sme_get_pmk_info(mac_handle_t mac_handle, uint8_t session_id,
|
||||
QDF_STATUS sme_roam_set_psk_pmk(mac_handle_t mac_handle, uint8_t sessionId,
|
||||
uint8_t *psk_pmk, size_t pmk_len,
|
||||
bool update_to_fw);
|
||||
|
||||
/**
|
||||
* sme_set_pmk_cache_ft() - a wrapper function to request CSR to save MDID
|
||||
* This is a synchronous call.
|
||||
* @mac_handle: Global structure
|
||||
* @session_id: SME session id
|
||||
* @pmk_cache: pointer to pmk cache structure wlan_crypto_pmksa
|
||||
*
|
||||
* Return: QDF_STATUS -status whether MDID is set or not
|
||||
*/
|
||||
QDF_STATUS sme_set_pmk_cache_ft(mac_handle_t mac_handle, uint8_t session_id,
|
||||
struct wlan_crypto_pmksa *pmk_cache);
|
||||
#else
|
||||
static inline
|
||||
void sme_get_pmk_info(mac_handle_t mac_handle, uint8_t session_id,
|
||||
@@ -624,6 +636,13 @@ QDF_STATUS sme_roam_set_psk_pmk(mac_handle_t mac_handle, uint8_t sessionId,
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline
|
||||
QDF_STATUS sme_set_pmk_cache_ft(mac_handle_t mac_handle, uint8_t session_id,
|
||||
struct wlan_crypto_pmksa *pmk_cache)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
QDF_STATUS sme_get_config_param(mac_handle_t mac_handle,
|
||||
|
@@ -3465,6 +3465,20 @@ QDF_STATUS sme_roam_set_psk_pmk(mac_handle_t mac_handle, uint8_t sessionId,
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS sme_set_pmk_cache_ft(mac_handle_t mac_handle, uint8_t session_id,
|
||||
struct wlan_crypto_pmksa *pmk_cache)
|
||||
{
|
||||
QDF_STATUS status = QDF_STATUS_E_FAILURE;
|
||||
struct mac_context *mac = MAC_CONTEXT(mac_handle);
|
||||
|
||||
status = sme_acquire_global_lock(&mac->sme);
|
||||
if (QDF_IS_STATUS_SUCCESS(status)) {
|
||||
status = csr_set_pmk_cache_ft(mac, session_id, pmk_cache);
|
||||
sme_release_global_lock(&mac->sme);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@@ -5665,19 +5665,34 @@ QDF_STATUS csr_roam_set_psk_pmk(struct mac_context *mac, uint8_t vdev_id,
|
||||
uint8_t *psk_pmk, size_t pmk_len,
|
||||
bool update_to_fw)
|
||||
{
|
||||
int32_t akm;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
wlan_cm_set_psk_pmk(mac->pdev, vdev_id, psk_pmk, pmk_len);
|
||||
if (update_to_fw)
|
||||
wlan_roam_update_cfg(mac->psoc, vdev_id,
|
||||
REASON_ROAM_PSK_PMK_CHANGED);
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id,
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS csr_set_pmk_cache_ft(struct mac_context *mac, uint32_t session_id,
|
||||
struct wlan_crypto_pmksa *pmk_cache)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
int32_t akm;
|
||||
|
||||
if (!CSR_IS_SESSION_VALID(mac, session_id)) {
|
||||
sme_err("session %d not found", session_id);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, session_id,
|
||||
WLAN_LEGACY_SME_ID);
|
||||
if (!vdev) {
|
||||
sme_err("vdev is NULL");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
wlan_cm_set_psk_pmk(mac->pdev, vdev_id, psk_pmk, pmk_len);
|
||||
|
||||
akm = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT);
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
|
||||
|
||||
if (QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_CCKM)) {
|
||||
sme_debug("PMK update is not required for ESE");
|
||||
return QDF_STATUS_SUCCESS;
|
||||
@@ -5688,13 +5703,32 @@ QDF_STATUS csr_roam_set_psk_pmk(struct mac_context *mac, uint8_t vdev_id,
|
||||
QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FILS_SHA384) ||
|
||||
QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384)) {
|
||||
sme_debug("Auth type: %x update the MDID in cache", akm);
|
||||
cm_update_pmk_cache_ft(mac->psoc, vdev_id);
|
||||
cm_update_pmk_cache_ft(mac->psoc, session_id);
|
||||
} else {
|
||||
struct cm_roam_values_copy src_cfg;
|
||||
QDF_STATUS status = QDF_STATUS_E_FAILURE;
|
||||
tCsrScanResultInfo *scan_res;
|
||||
|
||||
scan_res = qdf_mem_malloc(sizeof(tCsrScanResultInfo));
|
||||
if (!scan_res)
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
status = csr_scan_get_result_for_bssid(mac, &pmk_cache->bssid,
|
||||
scan_res);
|
||||
if (QDF_IS_STATUS_SUCCESS(status) &&
|
||||
scan_res->BssDescriptor.mdiePresent) {
|
||||
sme_debug("Update MDID in cache from scan_res");
|
||||
src_cfg.bool_value = true;
|
||||
src_cfg.uint_value =
|
||||
(scan_res->BssDescriptor.mdie[0] |
|
||||
(scan_res->BssDescriptor.mdie[1] << 8));
|
||||
wlan_cm_roam_cfg_set_value(mac->psoc, session_id,
|
||||
MOBILITY_DOMAIN, &src_cfg);
|
||||
cm_update_pmk_cache_ft(mac->psoc, session_id);
|
||||
}
|
||||
qdf_mem_free(scan_res);
|
||||
scan_res = NULL;
|
||||
}
|
||||
|
||||
if (update_to_fw)
|
||||
wlan_roam_update_cfg(mac->psoc, vdev_id,
|
||||
REASON_ROAM_PSK_PMK_CHANGED);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
|
||||
|
@@ -396,6 +396,18 @@ void csr_get_pmk_info(struct mac_context *mac_ctx, uint8_t session_id,
|
||||
QDF_STATUS csr_roam_set_psk_pmk(struct mac_context *mac, uint8_t vdev_id,
|
||||
uint8_t *psk_pmk, size_t pmk_len,
|
||||
bool update_to_fw);
|
||||
|
||||
/**
|
||||
* csr_set_pmk_cache_ft() - store MDID in PMK cache
|
||||
*
|
||||
* @mac - pointer to global structure for MAC
|
||||
* @session_id - Sme session id
|
||||
* @pmk_cache: pointer to a structure of PMK
|
||||
*
|
||||
* Return QDF_STATUS - usually it succeed unless session_id is not found
|
||||
*/
|
||||
QDF_STATUS csr_set_pmk_cache_ft(struct mac_context *mac, uint32_t session_id,
|
||||
struct wlan_crypto_pmksa *pmk_cache);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user