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