Browse Source

qcacmn: Delete igtk keys: key_idx 4 and 5 for PMF

Delete igtk keys of index 4, 5 if PMF configuration
is changed

Change-Id: I5f0de09fb713864a0e2cb3036633bf5c131e1f8c
Nandha Kishore Easwaran 7 years ago
parent
commit
b0ac369215

+ 1 - 0
umac/cmn_services/crypto/inc/wlan_crypto_global_def.h

@@ -41,6 +41,7 @@
 #define WLAN_CRYPTO_EXT_IV_BIT       (0x20)
 #define WLAN_CRYPTO_KEYIX_NONE       ((uint16_t)-1)
 #define WLAN_CRYPTO_MAXKEYIDX        (4)
+#define WLAN_CRYPTO_MAXIGTKKEYIDX    (2)
 
 /* 40 bit wep key len */
 #define WLAN_CRYPTO_KEY_WEP40_LEN    (5)

+ 3 - 2
umac/cmn_services/crypto/src/wlan_crypto_def_i.h

@@ -393,10 +393,11 @@ struct wlan_crypto_mmie {
 
 struct wlan_crypto_comp_priv {
 	struct wlan_crypto_params crypto_params;
-	struct wlan_crypto_key *key[4];
-	struct wlan_crypto_key *igtk_key;
+	struct wlan_crypto_key *key[WLAN_CRYPTO_MAXKEYIDX];
+	struct wlan_crypto_key *igtk_key[WLAN_CRYPTO_MAXIGTKKEYIDX];
 	uint32_t igtk_key_type;
 	uint8_t def_tx_keyid;
+	uint8_t def_igtk_tx_keyid;
 };
 
 

+ 59 - 17
umac/cmn_services/crypto/src/wlan_crypto_global_api.c

@@ -276,6 +276,7 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev,
 	uint8_t macaddr[WLAN_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 	bool isbcast;
 	enum QDF_OPMODE vdev_mode;
+	uint8_t igtk_idx = 0;
 
 	if (!vdev || !req_key || req_key->keylen > (sizeof(req_key->keydata))) {
 		qdf_print("%s[%d] Invalid params vdev%pK, req_key%pK\n",
@@ -367,14 +368,25 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev,
 		}
 
 		if (IS_MGMT_CIPHER(req_key->type)) {
+			igtk_idx = req_key->keyix - WLAN_CRYPTO_MAXKEYIDX;
+			if (igtk_idx > WLAN_CRYPTO_MAXIGTKKEYIDX) {
+				qdf_print("%s[%d] igtk key invalid keyid %d \n",
+						  __func__, __LINE__, igtk_idx);
+				return QDF_STATUS_E_INVAL;
+			}
 			key = qdf_mem_malloc(sizeof(struct wlan_crypto_key));
 			if (key == NULL) {
 				qdf_print("%s[%d] igtk key alloc failed\n",
 						__func__, __LINE__);
 				return QDF_STATUS_E_NOMEM;
 			}
-			crypto_priv->igtk_key = key;
+
+			if (crypto_priv->igtk_key[igtk_idx])
+				qdf_mem_free(crypto_priv->igtk_key[igtk_idx]);
+
+			crypto_priv->igtk_key[igtk_idx] = key;
 			crypto_priv->igtk_key_type = req_key->type;
+			crypto_priv->def_igtk_tx_keyid = igtk_idx;
 		} else {
 			if (!HAS_MCAST_CIPHER(crypto_params, req_key->type)
 				&& (req_key->type != WLAN_CRYPTO_CIPHER_WEP)) {
@@ -397,7 +409,7 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev,
 				qdf_print("%s[%d] peer %pK failed\n",
 						__func__, __LINE__, peer);
 				if (IS_MGMT_CIPHER(req_key->type)) {
-					crypto_priv->igtk_key = NULL;
+					crypto_priv->igtk_key[igtk_idx] = NULL;
 					crypto_priv->igtk_key_type
 						= WLAN_CRYPTO_CIPHER_NONE;
 				} else
@@ -433,13 +445,24 @@ QDF_STATUS wlan_crypto_setkey(struct wlan_objmgr_vdev *vdev,
 			return QDF_STATUS_E_INVAL;
 		}
 		if (IS_MGMT_CIPHER(req_key->type)) {
+			igtk_idx = req_key->keyix - WLAN_CRYPTO_MAXKEYIDX;
+			if (igtk_idx > WLAN_CRYPTO_MAXIGTKKEYIDX) {
+				qdf_print("%s[%d] igtk key invalid keyid %d \n",
+						  __func__, __LINE__, igtk_idx);
+				return QDF_STATUS_E_INVAL;
+			}
 			key = qdf_mem_malloc(sizeof(struct wlan_crypto_key));
 			if (key == NULL) {
 				qdf_print("%s[%d] igtk key alloc failed\n",
 						__func__, __LINE__);
 				return QDF_STATUS_E_NOMEM;
 			}
-			crypto_priv->igtk_key = key;
+			if (crypto_priv->igtk_key[igtk_idx])
+				qdf_mem_free(crypto_priv->igtk_key[igtk_idx]);
+
+			crypto_priv->igtk_key[igtk_idx] = key;
+			crypto_priv->igtk_key_type = req_key->type;
+			crypto_priv->def_igtk_tx_keyid = igtk_idx;
 		} else {
 			uint16_t kid = req_key->keyix;
 			if (kid == WLAN_CRYPTO_KEYIX_NONE)
@@ -668,7 +691,9 @@ QDF_STATUS wlan_crypto_delkey(struct wlan_objmgr_vdev *vdev,
 	struct wlan_objmgr_psoc *psoc;
 	uint8_t bssid_mac[WLAN_ALEN];
 
-	if (!vdev || !macaddr || (key_idx >= WLAN_CRYPTO_MAXKEYIDX)) {
+	if (!vdev || !macaddr ||
+		(key_idx >
+			(WLAN_CRYPTO_MAXKEYIDX + WLAN_CRYPTO_MAXIGTKKEYIDX))) {
 		qdf_print("%s[%d] Invalid params vdev %pK, macaddr %pK"
 					"keyidx %d\n", __func__, __LINE__, vdev,
 					macaddr, key_idx);
@@ -693,11 +718,6 @@ QDF_STATUS wlan_crypto_delkey(struct wlan_objmgr_vdev *vdev,
 							__func__, __LINE__);
 			return QDF_STATUS_E_INVAL;
 		}
-
-		key = crypto_priv->key[key_idx];
-		if (!key)
-			return QDF_STATUS_E_INVAL;
-		crypto_priv->key[key_idx] = NULL;
 	} else {
 		struct wlan_objmgr_peer *peer;
 
@@ -716,12 +736,21 @@ QDF_STATUS wlan_crypto_delkey(struct wlan_objmgr_vdev *vdev,
 							__func__, __LINE__);
 			return QDF_STATUS_E_INVAL;
 		}
+	}
 
+	if (key_idx >= WLAN_CRYPTO_MAXKEYIDX) {
+		uint8_t igtk_idx = key_idx - WLAN_CRYPTO_MAXKEYIDX;
+		key = crypto_priv->igtk_key[igtk_idx];
+		crypto_priv->igtk_key[igtk_idx] = NULL;
+		key->valid = 0;
+	} else {
 		key = crypto_priv->key[key_idx];
-		if (!key)
-			return QDF_STATUS_E_INVAL;
 		crypto_priv->key[key_idx] = NULL;
 	}
+
+	if (!key)
+		return QDF_STATUS_E_INVAL;
+
 	if (key->valid) {
 		cipher_table = (struct wlan_crypto_cipher *)key->cipher_table;
 
@@ -1258,7 +1287,13 @@ uint8_t *wlan_crypto_add_mmie(struct wlan_objmgr_vdev *vdev,
 		return NULL;
 	}
 
-	key = crypto_priv->igtk_key;
+	if (crypto_priv->def_igtk_tx_keyid > WLAN_CRYPTO_MAXIGTKKEYIDX) {
+		qdf_print("%s[%d] igtk key invalid keyid %d \n",
+			__func__, __LINE__, crypto_priv->def_igtk_tx_keyid);
+		return NULL;
+	}
+
+	key = crypto_priv->igtk_key[crypto_priv->def_igtk_tx_keyid];
 	if (!key) {
 		qdf_print("%s[%d] No igtk key present\n", __func__, __LINE__);
 		return NULL;
@@ -1396,11 +1431,6 @@ bool wlan_crypto_is_mmie_valid(struct wlan_objmgr_vdev *vdev,
 
 	crypto_params = &(crypto_priv->crypto_params);
 
-	key = crypto_priv->igtk_key;
-	if (!key) {
-		qdf_print("%s[%d] No igtk key present\n", __func__, __LINE__);
-		return false;
-	}
 
 	mic_len = (crypto_priv->igtk_key_type
 			== WLAN_CRYPTO_CIPHER_AES_CMAC) ? 8 : 16;
@@ -1418,6 +1448,18 @@ bool wlan_crypto_is_mmie_valid(struct wlan_objmgr_vdev *vdev,
 		return false;
 	}
 
+	if (mmie->key_id > (WLAN_CRYPTO_MAXKEYIDX +
+				WLAN_CRYPTO_MAXIGTKKEYIDX)) {
+		qdf_print("%s[%d] keyid not valid\n", __func__, __LINE__);
+		return false;
+	}
+
+	key = crypto_priv->igtk_key[mmie->key_id - WLAN_CRYPTO_MAXKEYIDX];
+	if (!key) {
+		qdf_print("%s[%d] No igtk key present\n", __func__, __LINE__);
+		return false;
+	}
+
 	/* validate ipn */
 	ipn = mmie->sequence_number;
 	if (qdf_mem_cmp(ipn, key->keyrsc, 6) <= 0) {

+ 5 - 3
umac/cmn_services/crypto/src/wlan_crypto_obj_mgr.c

@@ -204,9 +204,11 @@ static void wlan_crypto_free_key(struct wlan_crypto_comp_priv *crypto_priv)
 		}
 	}
 
-	if (crypto_priv->igtk_key) {
-		qdf_mem_free(crypto_priv->igtk_key);
-		crypto_priv->igtk_key = NULL;
+	for (i = 0; i < WLAN_CRYPTO_MAXIGTKKEYIDX; i++) {
+		if (crypto_priv->igtk_key[i]) {
+			qdf_mem_free(crypto_priv->igtk_key[i]);
+			crypto_priv->igtk_key[i] = NULL;
+		}
 	}
 
 }