qcacmn: Add pmksa based on SSID and cache id
For FILS pmksa cache, the pmksa add/del/query is based on SSID
and cache id. The current crypto pmksa cache API dosn't support
SSID and cache ID..
1. Add SSID/Cache ID support to pmksa API
2. Add RSN IE pmkid field based on SSID/cache ID
Change-Id: I1577c6293b75d6f8e6210f314dd83462e06d8190
CRs-Fixed: 2621860
diff --git a/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h b/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h
index 7f8a2b7..be28bda 100644
--- a/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h
+++ b/umac/cmn_services/crypto/inc/wlan_crypto_global_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -320,6 +320,21 @@
*/
uint8_t *wlan_crypto_build_wpaie(struct wlan_objmgr_vdev *vdev,
uint8_t *iebuf);
+
+/**
+ * wlan_crypto_build_rsnie_with_pmksa() - called by mlme to build rsnie
+ * @vdev: vdev
+ * @iebuf: ie buffer
+ * @pmksa: pmksa struct
+ *
+ * This function gets called by mlme to build rsnie from given vdev
+ *
+ * Return: end of buffer
+ */
+uint8_t *wlan_crypto_build_rsnie_with_pmksa(struct wlan_objmgr_vdev *vdev,
+ uint8_t *iebuf,
+ struct wlan_crypto_pmksa *pmksa);
+
/**
* wlan_crypto_build_rsnie - called by mlme to build rsnie
* @vdev: vdev
@@ -852,6 +867,20 @@
return QDF_STATUS_SUCCESS;
}
#endif /* CRYPTO_SET_KEY_CONVERGED */
+
+/**
+ * wlan_crypto_get_peer_pmksa() - called to get pmksa based on pmksa parameter
+ * @vdev: vdev
+ * @pmksa: bssid
+ *
+ * This function is to get pmksa based on pmksa parameter
+ *
+ * Return: wlan_crypto_pmksa when match found else NULL.
+ */
+struct wlan_crypto_pmksa *
+wlan_crypto_get_peer_pmksa(struct wlan_objmgr_vdev *vdev,
+ struct wlan_crypto_pmksa *pmksa);
+
/**
* wlan_crypto_get_pmksa - called to get pmksa of bssid passed.
* @vdev: vdev
diff --git a/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h b/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h
index 607cc78..73a607c 100644
--- a/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h
+++ b/umac/cmn_services/crypto/inc/wlan_crypto_global_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -223,12 +223,14 @@
* @pmk: pmk info
* @pmk_len: pmk len
*/
-
struct wlan_crypto_pmksa {
struct qdf_mac_addr bssid;
uint8_t pmkid[PMKID_LEN];
uint8_t pmk[MAX_PMK_LEN];
uint8_t pmk_len;
+ uint8_t ssid_len;
+ uint8_t ssid[WLAN_SSID_MAX_LEN];
+ uint8_t cache_id[WLAN_CACHE_ID_LEN];
};
/**
diff --git a/umac/cmn_services/crypto/src/wlan_crypto_global_api.c b/umac/cmn_services/crypto/src/wlan_crypto_global_api.c
index ce97b1c..49b667f 100644
--- a/umac/cmn_services/crypto/src/wlan_crypto_global_api.c
+++ b/umac/cmn_services/crypto/src/wlan_crypto_global_api.c
@@ -336,6 +336,19 @@
qdf_mem_free(crypto_params->pmksa[i]);
crypto_params->pmksa[i] = pmksa;
return QDF_STATUS_SUCCESS;
+ } else if (pmksa->ssid_len &&
+ !qdf_mem_cmp(pmksa->ssid,
+ crypto_params->pmksa[i]->ssid,
+ pmksa->ssid_len) &&
+ !qdf_mem_cmp(pmksa->cache_id,
+ crypto_params->pmksa[i]->cache_id,
+ WLAN_CACHE_ID_LEN)){
+ /* free the current pmksa and use this slot */
+ qdf_mem_zero(crypto_params->pmksa[i],
+ sizeof(struct wlan_crypto_pmksa));
+ qdf_mem_free(crypto_params->pmksa[i]);
+ crypto_params->pmksa[i] = pmksa;
+ return QDF_STATUS_SUCCESS;
}
}
@@ -365,10 +378,22 @@
qdf_mem_free(crypto_params->pmksa[i]);
crypto_params->pmksa[i] = NULL;
return QDF_STATUS_SUCCESS;
+ } else if (pmksa->ssid_len &&
+ !qdf_mem_cmp(pmksa->ssid,
+ crypto_params->pmksa[i]->ssid,
+ pmksa->ssid_len) &&
+ !qdf_mem_cmp(pmksa->cache_id,
+ crypto_params->pmksa[i]->cache_id,
+ WLAN_CACHE_ID_LEN)){
+ qdf_mem_zero(crypto_params->pmksa[i],
+ sizeof(struct wlan_crypto_pmksa));
+ qdf_mem_free(crypto_params->pmksa[i]);
+ crypto_params->pmksa[i] = NULL;
+ return QDF_STATUS_SUCCESS;
}
}
- return QDF_STATUS_E_INVAL;
+ return QDF_STATUS_SUCCESS;
}
QDF_STATUS wlan_crypto_pmksa_flush(struct wlan_crypto_params *crypto_params)
@@ -429,6 +454,48 @@
}
struct wlan_crypto_pmksa *
+wlan_crypto_get_peer_pmksa(struct wlan_objmgr_vdev *vdev,
+ struct wlan_crypto_pmksa *pmksa)
+{
+ struct wlan_crypto_comp_priv *crypto_priv;
+ struct wlan_crypto_params *crypto_params;
+ uint8_t i;
+
+ if (!pmksa) {
+ crypto_err("pmksa is NULL");
+ return NULL;
+ }
+ crypto_priv = (struct wlan_crypto_comp_priv *)
+ wlan_get_vdev_crypto_obj(vdev);
+
+ if (!crypto_priv) {
+ crypto_err("crypto_priv NULL");
+ return NULL;
+ }
+
+ crypto_params = &crypto_priv->crypto_params;
+
+ for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) {
+ if (!crypto_params->pmksa[i])
+ continue;
+ if (qdf_is_macaddr_equal(&pmksa->bssid,
+ &crypto_params->pmksa[i]->bssid)) {
+ return crypto_params->pmksa[i];
+ } else if (pmksa->ssid_len &&
+ !qdf_mem_cmp(pmksa->ssid,
+ crypto_params->pmksa[i]->ssid,
+ pmksa->ssid_len) &&
+ !qdf_mem_cmp(pmksa->cache_id,
+ crypto_params->pmksa[i]->cache_id,
+ WLAN_CACHE_ID_LEN)){
+ return crypto_params->pmksa[i];
+ }
+ }
+
+ return NULL;
+}
+
+struct wlan_crypto_pmksa *
wlan_crypto_get_pmksa(struct wlan_objmgr_vdev *vdev, struct qdf_mac_addr *bssid)
{
struct wlan_crypto_comp_priv *crypto_priv;
@@ -460,6 +527,7 @@
return NULL;
}
+
/**
* wlan_crypto_is_htallowed - called to check is HT allowed for cipher
* @vdev: vdev
@@ -2632,19 +2700,9 @@
return frm;
}
-/**
- * wlan_crypto_build_rsnie - called by mlme to build rsnie
- * @vdev: vdev
- * @iebuf: ie buffer
- * @bssid: bssid mac address to add pmkid in rsnie
- *
- * This function gets called by mlme to build rsnie from given vdev
- *
- * Return: end of buffer
- */
-uint8_t *wlan_crypto_build_rsnie(struct wlan_objmgr_vdev *vdev,
- uint8_t *iebuf,
- struct qdf_mac_addr *bssid)
+uint8_t *wlan_crypto_build_rsnie_with_pmksa(struct wlan_objmgr_vdev *vdev,
+ uint8_t *iebuf,
+ struct wlan_crypto_pmksa *pmksa)
{
uint8_t *frm = iebuf;
uint8_t *selcnt;
@@ -2796,20 +2854,13 @@
/* optional capabilities */
if (crypto_params->rsn_caps & WLAN_CRYPTO_RSN_CAP_MFP_ENABLED) {
/* PMK list */
- if (bssid) {
- struct wlan_crypto_pmksa *pmksa;
-
- pmksa = wlan_crypto_get_pmksa(vdev, bssid);
-
- if (pmksa) {
- WLAN_CRYPTO_ADDSHORT(frm, 1);
- qdf_mem_copy(frm, pmksa->pmkid, PMKID_LEN);
- frm += PMKID_LEN;
- } else {
- WLAN_CRYPTO_ADDSHORT(frm, 0);
- }
- } else
+ if (pmksa) {
+ WLAN_CRYPTO_ADDSHORT(frm, 1);
+ qdf_mem_copy(frm, pmksa->pmkid, PMKID_LEN);
+ frm += PMKID_LEN;
+ } else {
WLAN_CRYPTO_ADDSHORT(frm, 0);
+ }
if (HAS_MGMT_CIPHER(crypto_params,
WLAN_CRYPTO_CIPHER_AES_CMAC)) {
@@ -2836,17 +2887,12 @@
}
} else {
/* PMK list */
- if (bssid) {
- struct wlan_crypto_pmksa *pmksa;
-
- pmksa = wlan_crypto_get_pmksa(vdev, bssid);
- if (pmksa) {
- WLAN_CRYPTO_ADDSHORT(frm, 1);
- qdf_mem_copy(frm, pmksa->pmkid, PMKID_LEN);
- frm += PMKID_LEN;
- } else {
- WLAN_CRYPTO_ADDSHORT(frm, 0);
- }
+ if (pmksa) {
+ WLAN_CRYPTO_ADDSHORT(frm, 1);
+ qdf_mem_copy(frm, pmksa->pmkid, PMKID_LEN);
+ frm += PMKID_LEN;
+ } else {
+ WLAN_CRYPTO_ADDSHORT(frm, 0);
}
}
@@ -2856,6 +2902,18 @@
return frm;
}
+uint8_t *wlan_crypto_build_rsnie(struct wlan_objmgr_vdev *vdev,
+ uint8_t *iebuf,
+ struct qdf_mac_addr *bssid)
+{
+ struct wlan_crypto_pmksa *pmksa = NULL;
+
+ if (bssid)
+ pmksa = wlan_crypto_get_pmksa(vdev, bssid);
+
+ return wlan_crypto_build_rsnie_with_pmksa(vdev, iebuf, pmksa);
+}
+
bool wlan_crypto_rsn_info(struct wlan_objmgr_vdev *vdev,
struct wlan_crypto_params *crypto_params){
struct wlan_crypto_params *my_crypto_params;
diff --git a/umac/cmn_services/inc/wlan_cmn.h b/umac/cmn_services/inc/wlan_cmn.h
index dff1998..88d0bd9 100644
--- a/umac/cmn_services/inc/wlan_cmn.h
+++ b/umac/cmn_services/inc/wlan_cmn.h
@@ -61,6 +61,8 @@
/* Max length of a SSID */
#define WLAN_SSID_MAX_LEN 32
+#define WLAN_CACHE_ID_LEN 2
+
/* Max sequence number */
#define WLAN_MAX_SEQ_NUM 4096