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