Procházet zdrojové kódy

qcacmn: Save and set the WEP key on connection completion

Save and set the WEP key on connection completion in connection
manager.

Change-Id: I78cd778d371accdf7888e418bcad9a4f8ce9f71a
CRs-Fixed: 2805751
gaurank kathpalia před 4 roky
rodič
revize
c5798d9910

+ 16 - 1
umac/mlme/connection_mgr/core/src/wlan_cm_connect.c

@@ -669,12 +669,26 @@ static void cm_update_security_filter(struct scan_filter *filter,
 static void cm_set_fils_wep_key(struct cnx_mgr *cm_ctx,
 				struct wlan_cm_connect_rsp *resp)
 {
+	int32_t cipher;
+	struct qdf_mac_addr broadcast_mac = QDF_MAC_ADDR_BCAST_INIT;
+
+	/* Check and set FILS keys */
 	if (cm_is_fils_connection(cm_ctx, resp)) {
 		cm_set_fils_key(cm_ctx, resp);
 		return;
 	}
+	/* Check and set WEP keys */
+	cipher = wlan_crypto_get_param(cm_ctx->vdev,
+				       WLAN_CRYPTO_PARAM_UCAST_CIPHER);
+	if (cipher < 0)
+		return;
 
-	/* set WEP keys */
+	if (!(cipher & (1 << WLAN_CRYPTO_CIPHER_WEP_40 |
+			1 << WLAN_CRYPTO_CIPHER_WEP_104)))
+		return;
+
+	cm_set_key(cm_ctx, true, 0, &resp->bssid);
+	cm_set_key(cm_ctx, false, 0, &broadcast_mac);
 }
 #else
 static inline QDF_STATUS
@@ -1241,6 +1255,7 @@ QDF_STATUS cm_connect_active(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id)
 	req = &cm_req->connect_req.req;
 	wlan_vdev_mlme_set_ssid(cm_ctx->vdev, req->ssid.ssid, req->ssid.length);
 	cm_fill_vdev_crypto_params(cm_ctx, req);
+	cm_store_wep_key(cm_ctx, &req->crypto, *cm_id);
 
 	status = cm_get_valid_candidate(cm_ctx, cm_req, NULL, NULL);
 	if (QDF_IS_STATUS_ERROR(status))

+ 19 - 0
umac/mlme/connection_mgr/core/src/wlan_cm_main_api.h

@@ -497,6 +497,25 @@ QDF_STATUS cm_set_key(struct cnx_mgr *cm_ctx, bool unicast,
 		      uint8_t key_idx, struct qdf_mac_addr *bssid);
 #endif
 
+#ifdef CONN_MGR_ADV_FEATURE
+/**
+ * cm_store_wep_key() - store wep keys in crypto on connect active
+ * @cm_ctx: connection manager context
+ * @crypto: connection crypto info
+ * @cm_id: cm_id of the connection
+ *
+ * Return: void
+ */
+void cm_store_wep_key(struct cnx_mgr *cm_ctx,
+		      struct wlan_cm_connect_crypto_info *crypto,
+		      wlan_cm_id cm_id);
+#else
+static inline void cm_store_wep_key(struct cnx_mgr *cm_ctx,
+				    struct wlan_cm_connect_crypto_info *crypto,
+				    wlan_cm_id cm_id)
+{}
+#endif
+
 #ifdef WLAN_FEATURE_FILS_SK
 /**
  * cm_store_fils_key() - store fils keys in crypto on connection complete

+ 72 - 2
umac/mlme/connection_mgr/core/src/wlan_cm_util.c

@@ -120,9 +120,20 @@ static inline void cm_req_lock_release(struct cnx_mgr *cm_ctx)
 QDF_STATUS cm_set_key(struct cnx_mgr *cm_ctx, bool unicast,
 		      uint8_t key_idx, struct qdf_mac_addr *bssid)
 {
+	enum wlan_crypto_cipher_type cipher;
 	struct wlan_crypto_key *crypto_key;
-
-	crypto_key = wlan_crypto_get_key(cm_ctx->vdev, key_idx);
+	uint8_t wep_key_idx = 0;
+
+	cipher = wlan_crypto_get_cipher(cm_ctx->vdev, unicast, key_idx);
+	if (IS_WEP_CIPHER(cipher)) {
+		wep_key_idx = wlan_crypto_get_default_key_idx(cm_ctx->vdev,
+							      !unicast);
+		crypto_key = wlan_crypto_get_key(cm_ctx->vdev, wep_key_idx);
+		qdf_mem_copy(crypto_key->macaddr, bssid->bytes,
+			     QDF_MAC_ADDR_SIZE);
+	} else {
+		crypto_key = wlan_crypto_get_key(cm_ctx->vdev, key_idx);
+	}
 
 	return wlan_crypto_set_key_req(cm_ctx->vdev, crypto_key, (unicast ?
 				       WLAN_CRYPTO_KEY_TYPE_UNICAST :
@@ -130,6 +141,65 @@ QDF_STATUS cm_set_key(struct cnx_mgr *cm_ctx, bool unicast,
 }
 #endif
 
+#ifdef CONN_MGR_ADV_FEATURE
+void cm_store_wep_key(struct cnx_mgr *cm_ctx,
+		      struct wlan_cm_connect_crypto_info *crypto,
+		      wlan_cm_id cm_id)
+{
+	struct wlan_crypto_key *crypto_key = NULL;
+	QDF_STATUS status;
+	enum wlan_crypto_cipher_type cipher_type;
+	struct wlan_cm_wep_key_params *wep_keys;
+
+	if (!(crypto->ciphers_pairwise & (1 << WLAN_CRYPTO_CIPHER_WEP_40 |
+					  1 << WLAN_CRYPTO_CIPHER_WEP_104)))
+		return;
+
+	if (crypto->ciphers_pairwise & 1 << WLAN_CRYPTO_CIPHER_WEP_40)
+		cipher_type = WLAN_CRYPTO_CIPHER_WEP_40;
+	else
+		cipher_type = WLAN_CRYPTO_CIPHER_WEP_104;
+
+	wep_keys = &crypto->wep_keys;
+	status = wlan_crypto_validate_key_params(cipher_type,
+						 wep_keys->key_idx,
+						 wep_keys->key_len,
+						 wep_keys->seq_len);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		mlme_err(CM_PREFIX_FMT "Invalid key params",
+			 CM_PREFIX_REF(wlan_vdev_get_id(cm_ctx->vdev), cm_id));
+		return;
+	}
+
+	crypto_key = wlan_crypto_get_key(cm_ctx->vdev, wep_keys->key_idx);
+	if (!crypto_key) {
+		crypto_key = qdf_mem_malloc(sizeof(*crypto_key));
+		if (!crypto_key)
+			return;
+
+		status = wlan_crypto_save_key(cm_ctx->vdev, wep_keys->key_idx,
+					      crypto_key);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			mlme_err(CM_PREFIX_FMT "Failed to save key",
+				 CM_PREFIX_REF(wlan_vdev_get_id(cm_ctx->vdev),
+					       cm_id));
+			qdf_mem_free(crypto_key);
+			return;
+		}
+	}
+	qdf_mem_zero(crypto_key, sizeof(*crypto_key));
+	crypto_key->cipher_type = cipher_type;
+	crypto_key->keylen = wep_keys->key_len;
+	crypto_key->keyix = wep_keys->key_idx;
+	qdf_mem_copy(&crypto_key->keyval[0], wep_keys->key, wep_keys->key_len);
+	qdf_mem_copy(&crypto_key->keyrsc[0], wep_keys->seq, wep_keys->seq_len);
+	mlme_debug(CM_PREFIX_FMT "cipher_type %d key_len %d, seq_len %d",
+		   CM_PREFIX_REF(wlan_vdev_get_id(cm_ctx->vdev), cm_id),
+		   crypto_key->cipher_type, wep_keys->key_len,
+		   wep_keys->seq_len);
+}
+#endif
+
 #ifdef WLAN_FEATURE_FILS_SK
 void cm_store_fils_key(struct cnx_mgr *cm_ctx, bool unicast,
 		       uint8_t key_id, uint16_t key_length,