qcacld-3.0: Add pmksa based on SSID and cache id

For FILS pmksa cache, the pmksa add/del/query is based on SSID
and cache id.
1. Add SSID/Cache ID to pmksa cache using pmksa API.
2. Set PMK to csr session if PMK is present, PMK will be sent
to FW in RSO command.

Change-Id: I88a3e70a50565300ebab9723b439ee7674788b55
CRs-Fixed: 2621846
This commit is contained in:
Abhinav Kumar 2020-02-05 14:10:36 +08:00 • committed by nshrivas
commit fa7afb9c0f
3 changed files with 115 additions and 10 deletions

View file

@ -21251,6 +21251,18 @@ static QDF_STATUS wlan_hdd_set_pmksa_cache(struct hdd_adapter *adapter,
QDF_STATUS result;
struct wlan_crypto_pmksa *pmksa;
struct wlan_objmgr_vdev *vdev;
mac_handle_t mac_handle;
struct hdd_context *hdd_ctx;
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
if (!hdd_ctx) {
hdd_err("HDD context is null");
return QDF_STATUS_E_INVAL;
}
if (wlan_hdd_validate_context(hdd_ctx))
return QDF_STATUS_E_INVAL;
mac_handle = hdd_ctx->mac_handle;
vdev = hdd_objmgr_get_vdev(adapter);
if (!vdev)
@ -21261,7 +21273,15 @@ static QDF_STATUS wlan_hdd_set_pmksa_cache(struct hdd_adapter *adapter,
hdd_objmgr_put_vdev(vdev);
return QDF_STATUS_E_NOMEM;
}
qdf_copy_macaddr(&pmksa->bssid, &pmk_cache->BSSID);
if (!pmk_cache->ssid_len) {
qdf_copy_macaddr(&pmksa->bssid, &pmk_cache->BSSID);
} else {
qdf_mem_copy(pmksa->ssid, pmk_cache->ssid, pmk_cache->ssid_len);
qdf_mem_copy(pmksa->cache_id, pmk_cache->cache_id,
WLAN_CACHE_ID_LEN);
pmksa->ssid_len = pmk_cache->ssid_len;
}
qdf_mem_copy(pmksa->pmkid, pmk_cache->PMKID, PMKID_LEN);
qdf_mem_copy(pmksa->pmk, pmk_cache->pmk, pmk_cache->pmk_len);
pmksa->pmk_len = pmk_cache->pmk_len;
@ -21274,6 +21294,9 @@ static QDF_STATUS wlan_hdd_set_pmksa_cache(struct hdd_adapter *adapter,
wlan_update_sae_single_pmk_info(vdev, pmk_cache);
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);
hdd_objmgr_put_vdev(vdev);
return result;
@ -21323,11 +21346,9 @@ QDF_STATUS wlan_hdd_flush_pmksa_cache(struct hdd_adapter *adapter)
static inline bool wlan_hdd_is_pmksa_valid(struct cfg80211_pmksa *pmksa)
{
if (!pmksa->bssid) {
hdd_warn("bssid (%pK) is NULL",
pmksa->bssid);
hdd_warn("bssid is NULL");
if (!pmksa->ssid || !pmksa->cache_id) {
hdd_err("either ssid (%pK) or cache_id (%pK) are NULL",
pmksa->ssid, pmksa->cache_id);
hdd_err("either ssid or cache_id are NULL");
return false;
}
}

View file

@ -618,6 +618,13 @@ sme_set_roam_scan_ch_event_cb(mac_handle_t mac_handle,
{
return QDF_STATUS_E_FAILURE;
}
static inline
QDF_STATUS sme_roam_set_psk_pmk(mac_handle_t mac_handle, uint8_t sessionId,
uint8_t *pPSK_PMK, size_t pmk_len)
{
return QDF_STATUS_SUCCESS;
}
#endif
/**

View file

@ -2746,6 +2746,56 @@ bool csr_lookup_pmkid_using_bssid(struct mac_context *mac,
return true;
}
/**
* csr_update_session_pmk() - Update the pmk len and pmk in the roam session
* @session: pointer to the CSR Roam session
* @pmkid_cache: pointer to the pmkid cache
*
* Return: None
*/
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
static void csr_update_session_pmk(struct csr_roam_session *session,
struct wlan_crypto_pmksa *pmksa)
{
session->pmk_len = pmksa->pmk_len;
qdf_mem_zero(session->psk_pmk, sizeof(session->psk_pmk));
qdf_mem_copy(session->psk_pmk, pmksa->pmk, session->pmk_len);
}
#else
static inline void csr_update_session_pmk(struct csr_roam_session *session,
struct wlan_crypto_pmksa *pmksa)
{
}
#endif
#ifdef WLAN_FEATURE_FILS_SK
/**
* csr_update_pmksa_to_profile() - update pmk and pmkid to profile which will be
* used in case of fils session
* @profile: profile
* @pmkid_cache: pmksa cache
*
* Return: None
*/
static inline void csr_update_pmksa_to_profile(struct csr_roam_profile *profile,
struct wlan_crypto_pmksa *pmksa)
{
if (!profile->fils_con_info)
return;
profile->fils_con_info->pmk_len = pmksa->pmk_len;
qdf_mem_copy(profile->fils_con_info->pmk,
pmksa->pmk, pmksa->pmk_len);
qdf_mem_copy(profile->fils_con_info->pmkid,
pmksa->pmkid, PMKID_LEN);
}
#else
static inline void csr_update_pmksa_to_profile(struct csr_roam_profile *profile,
struct wlan_crypto_pmksa *pmksa)
{
}
#endif
uint8_t csr_construct_rsn_ie(struct mac_context *mac, uint32_t sessionId,
struct csr_roam_profile *pProfile,
struct bss_description *pSirBssDesc,
@ -2757,7 +2807,8 @@ uint8_t csr_construct_rsn_ie(struct mac_context *mac, uint32_t sessionId,
uint8_t ie_len = 0;
tDot11fBeaconIEs *local_ap_ie = ap_ie;
uint16_t rsn_cap = 0;
struct qdf_mac_addr bssid;
struct wlan_crypto_pmksa pmksa, *pmksa_peer;
struct csr_roam_session *session = &mac->roam.roamSession[sessionId];
if (!local_ap_ie &&
(!QDF_IS_STATUS_SUCCESS(csr_get_parsed_bss_description_ies
@ -2783,17 +2834,43 @@ uint8_t csr_construct_rsn_ie(struct mac_context *mac, uint32_t sessionId,
rsn_cap &= (uint16_t)wlan_crypto_get_param(vdev,
WLAN_CRYPTO_PARAM_RSN_CAP);
wlan_crypto_set_vdev_param(vdev, WLAN_CRYPTO_PARAM_RSN_CAP, rsn_cap);
qdf_mem_copy(bssid.bytes, pSirBssDesc->bssId, QDF_MAC_ADDR_SIZE);
qdf_mem_zero(&pmksa, sizeof(pmksa));
if (pSirBssDesc->fils_info_element.is_cache_id_present) {
pmksa.ssid_len =
pProfile->SSIDs.SSIDList[0].SSID.length;
qdf_mem_copy(pmksa.ssid,
pProfile->SSIDs.SSIDList[0].SSID.ssId,
pProfile->SSIDs.SSIDList[0].SSID.length);
qdf_mem_copy(pmksa.cache_id,
pSirBssDesc->fils_info_element.cache_id,
CACHE_ID_LEN);
qdf_mem_copy(&pmksa.bssid,
pSirBssDesc->bssId, QDF_MAC_ADDR_SIZE);
} else {
qdf_mem_copy(&pmksa.bssid,
pSirBssDesc->bssId, QDF_MAC_ADDR_SIZE);
}
pmksa_peer = wlan_crypto_get_peer_pmksa(vdev, &pmksa);
qdf_mem_zero(&pmksa, sizeof(pmksa));
/*
* TODO: Add support for Adaptive 11r connection after
* call to csr_get_rsn_information is added here
*/
rsn_ie_end = wlan_crypto_build_rsnie(vdev, rsn_ie, &bssid);
rsn_ie_end = wlan_crypto_build_rsnie_with_pmksa(vdev, rsn_ie,
pmksa_peer);
if (rsn_ie_end)
ie_len = rsn_ie_end - rsn_ie;
/*
* If a PMK cache is found for the BSSID, then
* update the PMK in CSR session also as this
* will be sent to the FW during RSO.
*/
if (pmksa_peer) {
csr_update_session_pmk(session, pmksa_peer);
csr_update_pmksa_to_profile(pProfile, pmksa_peer);
}
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
return ie_len;