1 /*
2  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 /**
17  * DOC: wlan_hdd_wifi_pos_pasn.c
18  *
19  * WLAN Host Device Driver WIFI POSITION PASN authentication APIs implementation
20  */
21 
22 #include <linux/module.h>
23 #include <linux/kernel.h>
24 #include <linux/init.h>
25 #include <linux/wireless.h>
26 #include "osif_sync.h"
27 #include <wlan_hdd_includes.h>
28 #include <net/cfg80211.h>
29 #include "qdf_trace.h"
30 #include "qdf_types.h"
31 #include "wlan_hdd_wifi_pos_pasn.h"
32 #include "wifi_pos_pasn_api.h"
33 #include "wifi_pos_ucfg_i.h"
34 #include "wlan_crypto_global_api.h"
35 #include "wifi_pos_ucfg_i.h"
36 #include "wlan_nl_to_crypto_params.h"
37 #include "wlan_mlo_mgr_sta.h"
38 
39 const struct nla_policy
40 wifi_pos_pasn_auth_status_policy[QCA_WLAN_VENDOR_ATTR_MAX + 1] = {
41 	[QCA_WLAN_VENDOR_ATTR_PASN_ACTION] = {.type = NLA_U32},
42 	[QCA_WLAN_VENDOR_ATTR_PASN_PEERS] = {.type = NLA_NESTED},
43 };
44 
45 const struct nla_policy
46 wifi_pos_pasn_auth_policy[QCA_WLAN_VENDOR_ATTR_PASN_PEER_MAX + 1] = {
47 	[QCA_WLAN_VENDOR_ATTR_PASN_PEER_SRC_ADDR] = VENDOR_NLA_POLICY_MAC_ADDR,
48 	[QCA_WLAN_VENDOR_ATTR_PASN_PEER_MAC_ADDR] = VENDOR_NLA_POLICY_MAC_ADDR,
49 	[QCA_WLAN_VENDOR_ATTR_PASN_PEER_STATUS_SUCCESS] = {.type = NLA_FLAG},
50 	[QCA_WLAN_VENDOR_ATTR_PASN_PEER_LTF_KEYSEED_REQUIRED] = {
51 							.type = NLA_FLAG},
52 };
53 
54 const struct nla_policy
55 wifi_pos_pasn_set_ranging_ctx_policy[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_MAX + 1] = {
56 	[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_ACTION] = {
57 					.type = NLA_U32},
58 	[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_SRC_ADDR] =
59 					VENDOR_NLA_POLICY_MAC_ADDR,
60 	[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_PEER_MAC_ADDR] =
61 					VENDOR_NLA_POLICY_MAC_ADDR,
62 	[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_SHA_TYPE] = {
63 					.type = NLA_U32},
64 	[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_TK] = {
65 					.type = NLA_BINARY, .len = MAX_PMK_LEN},
66 	[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_CIPHER] = {
67 					.type = NLA_U32},
68 	[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_LTF_KEYSEED] = {
69 					.type = NLA_BINARY, .len = MAX_PMK_LEN},
70 };
71 
72 static int
wlan_hdd_cfg80211_send_pasn_auth_status(struct wiphy * wiphy,struct net_device * dev,const void * data,int data_len)73 wlan_hdd_cfg80211_send_pasn_auth_status(struct wiphy *wiphy,
74 					struct net_device *dev,
75 					const void *data, int data_len)
76 {
77 	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
78 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
79 	struct wlan_pasn_auth_status *pasn_data;
80 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
81 	struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_PASN_PEER_MAX + 1];
82 	struct nlattr *curr_attr;
83 	QDF_STATUS status = QDF_STATUS_SUCCESS;
84 	bool is_pasn_success = false;
85 	int ret, i = 0, rem;
86 
87 	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
88 		hdd_err("Command not allowed in FTM mode");
89 		return -EPERM;
90 	}
91 
92 	if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id))
93 		return -EINVAL;
94 
95 	ret = wlan_hdd_validate_context(hdd_ctx);
96 	if (ret)
97 		return ret;
98 
99 	if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
100 				    data, data_len,
101 				    wifi_pos_pasn_auth_status_policy)) {
102 		hdd_err_rl("Invalid PASN auth status attributes");
103 		return -EINVAL;
104 	}
105 
106 	if (!tb[QCA_WLAN_VENDOR_ATTR_PASN_PEERS]) {
107 		hdd_err_rl("No PASN peer");
108 		return -EINVAL;
109 	}
110 
111 	pasn_data = qdf_mem_malloc(sizeof(*pasn_data));
112 	if (!pasn_data)
113 		return -ENOMEM;
114 
115 	pasn_data->vdev_id = adapter->deflink->vdev_id;
116 	nla_for_each_nested(curr_attr, tb[QCA_WLAN_VENDOR_ATTR_PASN_PEERS],
117 			    rem) {
118 		if (wlan_cfg80211_nla_parse_nested(
119 			tb2, QCA_WLAN_VENDOR_ATTR_PASN_PEER_MAX, curr_attr,
120 			wifi_pos_pasn_auth_policy)) {
121 			hdd_err_rl("nla_parse failed");
122 			qdf_mem_free(pasn_data);
123 			return -EINVAL;
124 		}
125 
126 		is_pasn_success = nla_get_flag(
127 			tb2[QCA_WLAN_VENDOR_ATTR_PASN_PEER_STATUS_SUCCESS]);
128 		if (!is_pasn_success)
129 			pasn_data->auth_status[i].status =
130 					WLAN_PASN_AUTH_STATUS_PASN_FAILED;
131 
132 		hdd_debug("PASN auth status:%d",
133 			  pasn_data->auth_status[i].status);
134 
135 		if (tb2[QCA_WLAN_VENDOR_ATTR_PASN_PEER_MAC_ADDR]) {
136 			nla_memcpy(pasn_data->auth_status[i].peer_mac.bytes,
137 				   tb2[QCA_WLAN_VENDOR_ATTR_PASN_PEER_MAC_ADDR],
138 				   QDF_MAC_ADDR_SIZE);
139 			hdd_debug("Peer mac[%d]: " QDF_MAC_ADDR_FMT, i,
140 				  QDF_MAC_ADDR_REF(
141 				  pasn_data->auth_status[i].peer_mac.bytes));
142 		}
143 
144 		if (tb2[QCA_WLAN_VENDOR_ATTR_PASN_PEER_SRC_ADDR]) {
145 			nla_memcpy(pasn_data->auth_status[i].self_mac.bytes,
146 				   tb2[QCA_WLAN_VENDOR_ATTR_PASN_PEER_SRC_ADDR],
147 				   QDF_MAC_ADDR_SIZE);
148 			hdd_debug("Src addr[%d]: " QDF_MAC_ADDR_FMT, i,
149 				  QDF_MAC_ADDR_REF(
150 				  pasn_data->auth_status[i].self_mac.bytes));
151 		}
152 
153 		i++;
154 		pasn_data->num_peers++;
155 		if (pasn_data->num_peers >= WLAN_MAX_11AZ_PEERS) {
156 			hdd_err_rl("Invalid num_peers:%d",
157 				   pasn_data->num_peers);
158 			qdf_mem_free(pasn_data);
159 			return -EINVAL;
160 		}
161 	}
162 
163 	status = wifi_pos_send_pasn_auth_status(hdd_ctx->psoc, pasn_data);
164 	if (QDF_IS_STATUS_ERROR(status))
165 		hdd_err("Send pasn auth status failed");
166 
167 	qdf_mem_free(pasn_data);
168 	ret = qdf_status_to_os_return(status);
169 
170 	return ret;
171 }
172 
wlan_hdd_wifi_pos_send_pasn_auth_status(struct wiphy * wiphy,struct wireless_dev * wdev,const void * data,int data_len)173 int wlan_hdd_wifi_pos_send_pasn_auth_status(struct wiphy *wiphy,
174 					    struct wireless_dev *wdev,
175 					    const void *data, int data_len)
176 {
177 	struct osif_vdev_sync *vdev_sync;
178 	int errno;
179 
180 	errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
181 	if (errno)
182 		return errno;
183 
184 	errno = wlan_hdd_cfg80211_send_pasn_auth_status(wiphy, wdev->netdev,
185 							data, data_len);
186 
187 	osif_vdev_sync_op_stop(vdev_sync);
188 
189 	return errno;
190 }
191 
192 #define WLAN_PASN_AUTH_KEY_INDEX 0
193 
wlan_cfg80211_set_pasn_key(struct hdd_adapter * adapter,struct nlattr ** tb)194 static int wlan_cfg80211_set_pasn_key(struct hdd_adapter *adapter,
195 				      struct nlattr **tb)
196 {
197 	struct wlan_crypto_key *crypto_key;
198 	struct wlan_objmgr_vdev *vdev;
199 	struct wlan_objmgr_peer *peer;
200 	struct wlan_objmgr_psoc *psoc =
201 			adapter->hdd_ctx->psoc;
202 	struct qdf_mac_addr peer_mac = {0};
203 	struct wlan_pasn_auth_status *pasn_status;
204 	bool is_ltf_keyseed_required;
205 	QDF_STATUS status;
206 	int ret = 0;
207 	int cipher_len;
208 	uint32_t cipher;
209 
210 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink,
211 					   WLAN_WIFI_POS_CORE_ID);
212 	if (!vdev) {
213 		hdd_err("Key params is NULL");
214 		return -EINVAL;
215 	}
216 
217 	crypto_key = qdf_mem_malloc(sizeof(*crypto_key));
218 	if (!crypto_key) {
219 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_WIFI_POS_CORE_ID);
220 		return -ENOMEM;
221 	}
222 
223 	if (!tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_CIPHER]) {
224 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_WIFI_POS_CORE_ID);
225 		qdf_mem_free(crypto_key);
226 		return -EINVAL;
227 	}
228 
229 	cipher = nla_get_u32(
230 		tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_CIPHER]);
231 	crypto_key->cipher_type = osif_nl_to_crypto_cipher_type(cipher);
232 
233 	cipher_len = osif_nl_to_crypto_cipher_len(cipher);
234 	crypto_key->keylen =
235 		nla_len(tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_TK]);
236 	if (cipher_len < 0 || crypto_key->keylen < cipher_len ||
237 	    (crypto_key->keylen >
238 	     (WLAN_CRYPTO_KEYBUF_SIZE + WLAN_CRYPTO_MICBUF_SIZE))) {
239 		hdd_err_rl("Invalid key length %d", crypto_key->keylen);
240 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_WIFI_POS_CORE_ID);
241 		qdf_mem_free(crypto_key);
242 		return -EINVAL;
243 	}
244 
245 	crypto_key->keyix = WLAN_PASN_AUTH_KEY_INDEX;
246 	qdf_mem_copy(&crypto_key->keyval[0],
247 		     nla_data(tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_TK]),
248 		     crypto_key->keylen);
249 
250 	if (!tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_PEER_MAC_ADDR]) {
251 		hdd_err_rl("BSSID is not present");
252 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_WIFI_POS_CORE_ID);
253 		qdf_mem_free(crypto_key);
254 		return -EINVAL;
255 	}
256 
257 	qdf_mem_copy(crypto_key->macaddr,
258 		     nla_data(tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_PEER_MAC_ADDR]),
259 		     QDF_MAC_ADDR_SIZE);
260 	qdf_mem_copy(peer_mac.bytes,
261 		     nla_data(tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_PEER_MAC_ADDR]),
262 		     QDF_MAC_ADDR_SIZE);
263 
264 	hdd_debug("PASN unicast key opmode %d, key_len %d",
265 		  vdev->vdev_mlme.vdev_opmode,
266 		  crypto_key->keylen);
267 
268 	status = ucfg_crypto_set_key_req(vdev, crypto_key,
269 					 WLAN_CRYPTO_KEY_TYPE_UNICAST);
270 	if (QDF_IS_STATUS_ERROR(status)) {
271 		hdd_err("PASN set_key failed");
272 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_WIFI_POS_CORE_ID);
273 		qdf_mem_free(crypto_key);
274 		return -EFAULT;
275 	}
276 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_WIFI_POS_CORE_ID);
277 	qdf_mem_free(crypto_key);
278 
279 	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac.bytes,
280 					   WLAN_WIFI_POS_CORE_ID);
281 	if (!peer) {
282 		hdd_err("PASN peer is not found");
283 		return -EFAULT;
284 	}
285 
286 	/*
287 	 * If LTF key seed is not required for the peer, then update
288 	 * the source mac address for that peer by sending PASN auth
289 	 * status command.
290 	 * If LTF keyseed is required, then PASN Auth status command
291 	 * will be sent after LTF keyseed command.
292 	 */
293 	is_ltf_keyseed_required =
294 			ucfg_wifi_pos_is_ltf_keyseed_required_for_peer(peer);
295 	wlan_objmgr_peer_release_ref(peer, WLAN_WIFI_POS_CORE_ID);
296 	if (is_ltf_keyseed_required)
297 		return 0;
298 
299 	pasn_status = qdf_mem_malloc(sizeof(*pasn_status));
300 	if (!pasn_status)
301 		return -ENOMEM;
302 
303 	pasn_status->vdev_id = adapter->deflink->vdev_id;
304 	pasn_status->num_peers = 1;
305 
306 	qdf_mem_copy(pasn_status->auth_status[0].peer_mac.bytes,
307 		     peer_mac.bytes, QDF_MAC_ADDR_SIZE);
308 
309 	if (tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_SRC_ADDR])
310 		qdf_mem_copy(pasn_status->auth_status[0].self_mac.bytes,
311 			     nla_data(tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_SRC_ADDR]),
312 			     QDF_MAC_ADDR_SIZE);
313 
314 	status = wifi_pos_send_pasn_auth_status(psoc, pasn_status);
315 	if (QDF_IS_STATUS_ERROR(status))
316 		hdd_err("Send PASN auth status failed");
317 
318 	ret = qdf_status_to_os_return(status);
319 
320 	qdf_mem_free(pasn_status);
321 
322 	return ret;
323 }
324 
325 #define MLO_ALL_VDEV_LINK_ID -1
326 
327 #ifdef WLAN_FEATURE_11BE_MLO
328 static QDF_STATUS
wlan_hdd_cfg80211_send_set_ltf_keyseed_mlo_vdev(struct hdd_context * hdd_ctx,struct wlan_objmgr_vdev * vdev,struct hdd_adapter * adapter,struct wlan_crypto_ltf_keyseed_data * data,int link_id)329 wlan_hdd_cfg80211_send_set_ltf_keyseed_mlo_vdev(struct hdd_context *hdd_ctx,
330 						struct wlan_objmgr_vdev *vdev,
331 						struct hdd_adapter *adapter,
332 						struct wlan_crypto_ltf_keyseed_data *data,
333 						int link_id)
334 {
335 	struct wlan_objmgr_vdev *link_vdev;
336 	struct wlan_objmgr_peer *peer;
337 	uint16_t link, vdev_count = 0;
338 	struct qdf_mac_addr peer_link_mac;
339 	struct qdf_mac_addr original_mac;
340 	struct wlan_objmgr_vdev *wlan_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS] = {0};
341 	QDF_STATUS status;
342 	uint8_t vdev_id;
343 	struct wlan_hdd_link_info *link_info;
344 
345 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev))
346 		return QDF_STATUS_SUCCESS;
347 
348 	qdf_copy_macaddr(&peer_link_mac, &data->peer_mac_addr);
349 	qdf_copy_macaddr(&original_mac, &data->peer_mac_addr);
350 	mlo_sta_get_vdev_list(vdev, &vdev_count, wlan_vdev_list);
351 
352 	for (link = 0; link < vdev_count; link++) {
353 		link_vdev = wlan_vdev_list[link];
354 		vdev_id = wlan_vdev_get_id(link_vdev);
355 
356 		link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
357 		if (!link_info) {
358 			mlo_release_vdev_ref(link_vdev);
359 			continue;
360 		}
361 
362 		peer = NULL;
363 		switch (adapter->device_mode) {
364 		case QDF_SAP_MODE:
365 			if (wlan_vdev_mlme_is_mlo_vdev(link_vdev))
366 				peer = wlan_hdd_ml_sap_get_peer(
367 						link_vdev,
368 						peer_link_mac.bytes);
369 			break;
370 		case QDF_STA_MODE:
371 		default:
372 			peer = wlan_objmgr_vdev_try_get_bsspeer(link_vdev,
373 								WLAN_OSIF_ID);
374 			break;
375 		}
376 
377 		if (peer) {
378 			qdf_mem_copy(peer_link_mac.bytes,
379 				     wlan_peer_get_macaddr(peer),
380 				     QDF_MAC_ADDR_SIZE);
381 			wlan_objmgr_peer_release_ref(peer, WLAN_OSIF_ID);
382 
383 		} else if (wlan_vdev_mlme_is_mlo_link_vdev(link_vdev) &&
384 			   adapter->device_mode == QDF_STA_MODE) {
385 			status = wlan_hdd_mlo_copy_partner_addr_from_mlie(
386 						link_vdev, &peer_link_mac);
387 			if (QDF_IS_STATUS_ERROR(status)) {
388 				hdd_err("Failed to get peer address from ML IEs");
389 				mlo_release_vdev_ref(link_vdev);
390 				continue;
391 			}
392 		} else {
393 			hdd_err("Peer is null");
394 			mlo_release_vdev_ref(link_vdev);
395 			continue;
396 		}
397 
398 		qdf_copy_macaddr(&data->peer_mac_addr, &peer_link_mac);
399 		data->vdev_id = wlan_vdev_get_id(link_vdev);
400 
401 		status = wlan_crypto_set_ltf_keyseed(hdd_ctx->psoc, data);
402 		if (QDF_IS_STATUS_ERROR(status)) {
403 			hdd_err("Set LTF Keyseed failed vdev:%d for peer: "
404 				QDF_MAC_ADDR_FMT, data->vdev_id,
405 				QDF_MAC_ADDR_REF(data->peer_mac_addr.bytes));
406 			mlo_release_vdev_ref(link_vdev);
407 			continue;
408 		}
409 
410 		mlo_release_vdev_ref(link_vdev);
411 	}
412 	qdf_copy_macaddr(&data->peer_mac_addr, &original_mac);
413 
414 	return QDF_STATUS_SUCCESS;
415 }
416 #else
417 static inline QDF_STATUS
wlan_hdd_cfg80211_send_set_ltf_keyseed_mlo_vdev(struct hdd_context * hdd_ctx,struct wlan_objmgr_vdev * vdev,struct hdd_adapter * adapter,struct wlan_crypto_ltf_keyseed_data * data,int link_id)418 wlan_hdd_cfg80211_send_set_ltf_keyseed_mlo_vdev(struct hdd_context *hdd_ctx,
419 						struct wlan_objmgr_vdev *vdev,
420 						struct hdd_adapter *adapter,
421 						struct wlan_crypto_ltf_keyseed_data *data,
422 						int link_id)
423 {
424 	return QDF_STATUS_SUCCESS;
425 }
426 #endif
427 
428 static int
wlan_hdd_cfg80211_send_set_ltf_keyseed(struct wiphy * wiphy,struct net_device * dev,struct nlattr ** tb)429 wlan_hdd_cfg80211_send_set_ltf_keyseed(struct wiphy *wiphy,
430 				       struct net_device *dev,
431 				       struct nlattr **tb)
432 {
433 	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
434 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
435 	struct wlan_pasn_auth_status *pasn_auth_status;
436 	struct wlan_objmgr_peer *peer;
437 	struct wlan_objmgr_vdev *vdev;
438 	struct wlan_crypto_ltf_keyseed_data *data;
439 	QDF_STATUS status = QDF_STATUS_SUCCESS;
440 	bool is_ltf_keyseed_required;
441 	enum wlan_peer_type peer_type;
442 	int ret;
443 
444 	hdd_enter();
445 	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
446 		hdd_err("Command not allowed in FTM mode");
447 		return -EPERM;
448 	}
449 
450 	if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id))
451 		return -EINVAL;
452 
453 	ret = wlan_hdd_validate_context(hdd_ctx);
454 	if (ret)
455 		return ret;
456 
457 	data = qdf_mem_malloc(sizeof(*data));
458 	if (!data)
459 		return -ENOMEM;
460 
461 	data->vdev_id = adapter->deflink->vdev_id;
462 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(hdd_ctx->psoc,
463 						    data->vdev_id,
464 						    WLAN_WIFI_POS_OSIF_ID);
465 	if (!vdev) {
466 		hdd_err_rl("Vdev is not found for id:%d", data->vdev_id);
467 		ret = -EINVAL;
468 		goto err;
469 	}
470 
471 	if (!tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_PEER_MAC_ADDR]) {
472 		wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_OSIF_ID);
473 		hdd_err_rl("BSSID is not present");
474 		ret = -EINVAL;
475 		goto err;
476 	}
477 
478 	qdf_mem_copy(data->peer_mac_addr.bytes,
479 		     nla_data(tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_PEER_MAC_ADDR]),
480 		     QDF_MAC_ADDR_SIZE);
481 
482 	if (tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_SRC_ADDR])
483 		qdf_mem_copy(data->src_mac_addr.bytes,
484 			     nla_data(tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_SRC_ADDR]),
485 			     QDF_MAC_ADDR_SIZE);
486 
487 	data->key_seed_len =
488 		nla_len(tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_LTF_KEYSEED]);
489 	if (!data->key_seed_len ||
490 	    data->key_seed_len < WLAN_MIN_SECURE_LTF_KEYSEED_LEN ||
491 	    data->key_seed_len > WLAN_MAX_SECURE_LTF_KEYSEED_LEN) {
492 		wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_OSIF_ID);
493 		hdd_err_rl("Invalid key seed length:%d", data->key_seed_len);
494 		ret = -EINVAL;
495 		goto err;
496 	}
497 
498 	qdf_mem_copy(data->key_seed,
499 		     nla_data(tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_LTF_KEYSEED]),
500 		     data->key_seed_len);
501 
502 	/*
503 	 * For MLO vdev send set LTF keyseed command on each link for the link
504 	 * peer address similar to install key command
505 	 */
506 	if (wlan_vdev_mlme_is_mlo_vdev(vdev))
507 		status = wlan_hdd_cfg80211_send_set_ltf_keyseed_mlo_vdev(
508 						hdd_ctx, vdev, adapter,
509 						data, MLO_ALL_VDEV_LINK_ID);
510 	else
511 		status = wlan_crypto_set_ltf_keyseed(hdd_ctx->psoc, data);
512 
513 	wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_OSIF_ID);
514 
515 	if (QDF_IS_STATUS_ERROR(status)) {
516 		hdd_err("Set LTF Keyseed failed vdev_id:%d", data->vdev_id);
517 		ret = qdf_status_to_os_return(status);
518 		goto err;
519 	}
520 
521 	peer = wlan_objmgr_get_peer_by_mac(hdd_ctx->psoc,
522 					   data->peer_mac_addr.bytes,
523 					   WLAN_WIFI_POS_CORE_ID);
524 	if (!peer) {
525 		hdd_err_rl("PASN peer is not found");
526 		/*
527 		 * Auth status need not be sent for the BSS PASN
528 		 * peer. So, return if peer is not found
529 		 */
530 		ret = 0;
531 		goto err;
532 	}
533 
534 	/*
535 	 * PASN auth status command need not be sent for associated peer.
536 	 * It should be sent only for PASN peer type.
537 	 */
538 	peer_type = wlan_peer_get_peer_type(peer);
539 	if (peer_type != WLAN_PEER_RTT_PASN) {
540 		wlan_objmgr_peer_release_ref(peer, WLAN_WIFI_POS_CORE_ID);
541 		ret = 0;
542 		goto err;
543 	}
544 
545 	/*
546 	 * If LTF key seed is not required for the peer, then update
547 	 * the source mac address for that peer by sending PASN auth
548 	 * status command.
549 	 * If LTF keyseed is required, then PASN Auth status command
550 	 * will be sent after LTF keyseed command.
551 	 */
552 	is_ltf_keyseed_required =
553 			ucfg_wifi_pos_is_ltf_keyseed_required_for_peer(peer);
554 	wlan_objmgr_peer_release_ref(peer, WLAN_WIFI_POS_CORE_ID);
555 
556 	if (!is_ltf_keyseed_required) {
557 		ret = 0;
558 		goto err;
559 	}
560 
561 	/*
562 	 * Send PASN Auth status followed by SET LTF keyseed command to
563 	 * set the peer as authorized at firmware and firmware will start
564 	 * ranging after this.
565 	 */
566 	pasn_auth_status = qdf_mem_malloc(sizeof(*pasn_auth_status));
567 	if (!pasn_auth_status) {
568 		ret = -ENOMEM;
569 		goto err;
570 	}
571 
572 	pasn_auth_status->vdev_id = adapter->deflink->vdev_id;
573 	pasn_auth_status->num_peers = 1;
574 	qdf_mem_copy(pasn_auth_status->auth_status[0].peer_mac.bytes,
575 		     data->peer_mac_addr.bytes, QDF_MAC_ADDR_SIZE);
576 	qdf_mem_copy(pasn_auth_status->auth_status[0].self_mac.bytes,
577 		     data->src_mac_addr.bytes, QDF_MAC_ADDR_SIZE);
578 
579 	hdd_debug("vdev:%d Send pasn auth status", pasn_auth_status->vdev_id);
580 	status = wifi_pos_send_pasn_auth_status(hdd_ctx->psoc,
581 						pasn_auth_status);
582 	qdf_mem_free(pasn_auth_status);
583 	if (QDF_IS_STATUS_ERROR(status))
584 		hdd_err("Send PASN auth status failed");
585 
586 	ret = qdf_status_to_os_return(status);
587 err:
588 	qdf_mem_free(data);
589 	hdd_exit();
590 
591 	return ret;
592 }
593 
594 static int
__wlan_hdd_cfg80211_set_secure_ranging_context(struct wiphy * wiphy,struct wireless_dev * wdev,const void * data,int data_len)595 __wlan_hdd_cfg80211_set_secure_ranging_context(struct wiphy *wiphy,
596 					       struct wireless_dev *wdev,
597 					       const void *data, int data_len)
598 {
599 	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
600 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev);
601 	int errno = 0;
602 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_MAX + 1];
603 	struct qdf_mac_addr peer_mac;
604 
605 	hdd_enter();
606 
607 	if (wlan_cfg80211_nla_parse(tb,
608 				    QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_MAX,
609 				    data, data_len,
610 				    wifi_pos_pasn_set_ranging_ctx_policy)) {
611 		hdd_err_rl("Invalid PASN auth status attributes");
612 		return -EINVAL;
613 	}
614 
615 	if (!tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_ACTION]) {
616 		hdd_err_rl("Action attribute is missing");
617 		return -EINVAL;
618 	}
619 
620 	if (nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_ACTION]) ==
621 			QCA_WLAN_VENDOR_SECURE_RANGING_CTX_ACTION_ADD) {
622 		if (tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_TK] &&
623 		    nla_len(tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_TK])) {
624 			hdd_debug("Sec ranging CTX TK");
625 			errno = wlan_cfg80211_set_pasn_key(adapter, tb);
626 			if (errno)
627 				return errno;
628 		}
629 
630 		if (tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_LTF_KEYSEED] &&
631 		    nla_len(tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_LTF_KEYSEED])) {
632 			hdd_debug("Set LTF keyseed");
633 			errno = wlan_hdd_cfg80211_send_set_ltf_keyseed(wiphy,
634 								       wdev->netdev, tb);
635 			if (errno)
636 				return errno;
637 		}
638 	} else if (nla_get_u32(
639 			tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_ACTION]) ==
640 			QCA_WLAN_VENDOR_SECURE_RANGING_CTX_ACTION_DELETE) {
641 		if (!tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_PEER_MAC_ADDR]) {
642 			hdd_err_rl("Peer mac address attribute is missing");
643 			return -EINVAL;
644 		}
645 
646 		qdf_mem_copy(peer_mac.bytes,
647 			     nla_data(tb[QCA_WLAN_VENDOR_ATTR_SECURE_RANGING_CTX_PEER_MAC_ADDR]),
648 			     QDF_MAC_ADDR_SIZE);
649 		hdd_debug("Delete PASN peer" QDF_MAC_ADDR_FMT,
650 			  QDF_MAC_ADDR_REF(peer_mac.bytes));
651 		wifi_pos_send_pasn_peer_deauth(hdd_ctx->psoc, &peer_mac);
652 	}
653 
654 	hdd_exit();
655 
656 	return errno;
657 }
658 
659 int
wlan_hdd_cfg80211_set_secure_ranging_context(struct wiphy * wiphy,struct wireless_dev * wdev,const void * data,int data_len)660 wlan_hdd_cfg80211_set_secure_ranging_context(struct wiphy *wiphy,
661 					     struct wireless_dev *wdev,
662 					     const void *data, int data_len)
663 {
664 	int errno;
665 	struct osif_vdev_sync *vdev_sync;
666 
667 	errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
668 	if (errno)
669 		return errno;
670 
671 	errno = __wlan_hdd_cfg80211_set_secure_ranging_context(wiphy,
672 							       wdev,
673 							       data, data_len);
674 
675 	osif_vdev_sync_op_stop(vdev_sync);
676 
677 	return errno;
678 }
679