1 /*
2 * wpa_supplicant - PASN processing
3 *
4 * Copyright (C) 2019 Intel Corporation
5 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
6 *
7 * This software may be distributed under the terms of the BSD license.
8 * See README for more details.
9 */
10
11 #include "includes.h"
12
13 #include "common/ieee802_11_defs.h"
14 #include "common/ieee802_11_common.h"
15 #include "common/dragonfly.h"
16 #include "common/ptksa_cache.h"
17 #include "utils/eloop.h"
18 #include "drivers/driver.h"
19 #include "crypto/crypto.h"
20 #include "crypto/random.h"
21 #include "eap_common/eap_defs.h"
22 #include "rsn_supp/wpa.h"
23 #include "rsn_supp/wpa_ie.h"
24 #include "rsn_supp/pmksa_cache.h"
25 #include "wpa_supplicant_i.h"
26 #include "driver_i.h"
27 #include "bss.h"
28 #include "scan.h"
29 #include "config.h"
30 #include "sme.h"
31
32 static const int dot11RSNAConfigPMKLifetime = 43200;
33
34 struct wpa_pasn_auth_work {
35 u8 own_addr[ETH_ALEN];
36 u8 peer_addr[ETH_ALEN];
37 int akmp;
38 int cipher;
39 u16 group;
40 int network_id;
41 struct wpabuf *comeback;
42 unsigned int auth_alg;
43 int group_cipher;
44 int group_mgmt_cipher;
45 #ifdef CONFIG_ENC_ASSOC
46 u16 rsn_capab;
47 u8 *rsnxe_data;
48 bool is_ml_peer;
49 #endif /* CONFIG_ENC_ASSOC */
50 };
51
52
wpas_pasn_free_peer_password(struct pasn_peer * peer)53 static void wpas_pasn_free_peer_password(struct pasn_peer *peer)
54 {
55 str_clear_free(peer->password);
56 peer->password = NULL;
57 }
58
59
wpas_pasn_free_peer_comeback(struct pasn_peer * peer)60 static void wpas_pasn_free_peer_comeback(struct pasn_peer *peer)
61 {
62 os_free(peer->comeback);
63 peer->comeback = NULL;
64 }
65
66
wpas_pasn_free_peer(struct pasn_peer * peer)67 static void wpas_pasn_free_peer(struct pasn_peer *peer)
68 {
69 wpas_pasn_free_peer_password(peer);
70 wpas_pasn_free_peer_comeback(peer);
71 }
72
73
wpas_pasn_send_mlme(void * ctx,const u8 * data,size_t data_len,int noack,unsigned int freq,unsigned int wait)74 static int wpas_pasn_send_mlme(void *ctx, const u8 *data, size_t data_len,
75 int noack, unsigned int freq, unsigned int wait)
76 {
77 struct wpa_supplicant *wpa_s = ctx;
78
79 return wpa_drv_send_mlme(wpa_s, data, data_len, noack, freq, wait);
80 }
81
82
wpas_pasn_free_auth_work(struct wpa_pasn_auth_work * awork)83 static void wpas_pasn_free_auth_work(struct wpa_pasn_auth_work *awork)
84 {
85 wpabuf_free(awork->comeback);
86 awork->comeback = NULL;
87 #ifdef CONFIG_ENC_ASSOC
88 os_free(awork->rsnxe_data);
89 awork->rsnxe_data = NULL;
90 #endif /* CONFIG_ENC_ASSOC */
91 os_free(awork);
92 }
93
94
wpas_pasn_auth_work_timeout(void * eloop_ctx,void * timeout_ctx)95 static void wpas_pasn_auth_work_timeout(void *eloop_ctx, void *timeout_ctx)
96 {
97 struct wpa_supplicant *wpa_s = eloop_ctx;
98
99 wpa_printf(MSG_DEBUG, "PASN: Auth work timeout - stopping auth");
100
101 wpas_pasn_auth_stop(wpa_s);
102
103 wpas_pasn_auth_work_done(wpa_s, PASN_STATUS_FAILURE);
104 }
105
106
wpas_pasn_cancel_auth_work(struct wpa_supplicant * wpa_s)107 static void wpas_pasn_cancel_auth_work(struct wpa_supplicant *wpa_s)
108 {
109 wpa_printf(MSG_DEBUG, "PASN: Cancel pasn-start-auth work");
110
111 /* Remove pending/started work */
112 radio_remove_works(wpa_s, "pasn-start-auth", 0);
113 }
114
115
wpas_pasn_auth_status(struct wpa_supplicant * wpa_s,const u8 * peer_addr,int akmp,int cipher,u8 status,struct wpabuf * comeback,u16 comeback_after)116 static void wpas_pasn_auth_status(struct wpa_supplicant *wpa_s,
117 const u8 *peer_addr,
118 int akmp, int cipher, u8 status,
119 struct wpabuf *comeback,
120 u16 comeback_after)
121 {
122 if (comeback) {
123 size_t comeback_len = wpabuf_len(comeback);
124 size_t buflen = comeback_len * 2 + 1;
125 char *comeback_txt = os_malloc(buflen);
126
127 if (comeback_txt) {
128 wpa_snprintf_hex(comeback_txt, buflen,
129 wpabuf_head(comeback), comeback_len);
130
131 wpa_msg(wpa_s, MSG_INFO, PASN_AUTH_STATUS MACSTR
132 " akmp=%s, status=%u comeback_after=%u comeback=%s",
133 MAC2STR(peer_addr),
134 wpa_key_mgmt_txt(akmp, WPA_PROTO_RSN),
135 status, comeback_after, comeback_txt);
136
137 os_free(comeback_txt);
138 return;
139 }
140 }
141
142 wpa_msg(wpa_s, MSG_INFO,
143 PASN_AUTH_STATUS MACSTR " akmp=%s, status=%u",
144 MAC2STR(peer_addr), wpa_key_mgmt_txt(akmp, WPA_PROTO_RSN),
145 status);
146 }
147
148
149 #ifdef CONFIG_SAE
150
151 static struct sae_pt *
wpas_pasn_sae_derive_pt(struct wpa_ssid * ssid,int group)152 wpas_pasn_sae_derive_pt(struct wpa_ssid *ssid, int group)
153 {
154 const char *password = ssid->sae_password;
155 int groups[2] = { group, 0 };
156
157 if (!password)
158 password = ssid->passphrase;
159
160 if (!password) {
161 wpa_printf(MSG_DEBUG, "PASN: SAE without a password");
162 return NULL;
163 }
164
165 return sae_derive_pt(groups, ssid->ssid, ssid->ssid_len,
166 (const u8 *) password, os_strlen(password),
167 (const u8 *) ssid->sae_password_id,
168 ssid->sae_password_id ?
169 os_strlen(ssid->sae_password_id) : 0);
170 }
171
172
173 #ifdef CONFIG_ENC_ASSOC
174 struct sae_pt *
wpas_pasn_sae_derive_pt_for_eppke(struct wpa_ssid * ssid,int group)175 wpas_pasn_sae_derive_pt_for_eppke(struct wpa_ssid *ssid, int group)
176 {
177 const char *password = ssid->sae_password;
178 int groups[2] = { group, 0 };
179 const u8 *password_id = NULL;
180 size_t password_id_len = 0;
181
182 if (!password)
183 password = ssid->passphrase;
184
185 if (!password) {
186 wpa_printf(MSG_DEBUG, "EPPKE: SAE without a password");
187 return NULL;
188 }
189
190 /* Prefer an alternative (changing) password identifier if available */
191 if (ssid->alt_sae_password_ids && ssid->alt_sae_password_ids->num) {
192 unsigned int idx =
193 os_random() % ssid->alt_sae_password_ids->num;
194 struct wpabuf *id = ssid->alt_sae_password_ids->buf[idx];
195
196 password_id = wpabuf_head(id);
197 password_id_len = wpabuf_len(id);
198 wpa_hexdump(MSG_DEBUG,
199 "EPPKE: Prepare PT for alternative password ID",
200 password_id, password_id_len);
201 ssid->alt_sae_passwords_ids_idx = idx;
202 ssid->alt_sae_passwords_ids_used = true;
203 } else if (ssid->sae_password_id) {
204 password_id = (const u8 *) ssid->sae_password_id;
205 password_id_len = os_strlen(ssid->sae_password_id);
206 }
207
208 return sae_derive_pt(groups, ssid->ssid, ssid->ssid_len,
209 (const u8 *) password, os_strlen(password),
210 password_id, password_id_len);
211 }
212 #endif /* CONFIG_ENC_ASSOC */
213
214
wpas_pasn_sae_setup_pt(struct wpa_ssid * ssid,int group)215 static int wpas_pasn_sae_setup_pt(struct wpa_ssid *ssid, int group)
216 {
217 if (!ssid->sae_password && !ssid->passphrase) {
218 wpa_printf(MSG_DEBUG, "PASN: SAE without a password");
219 return -1;
220 }
221
222 if (ssid->pt)
223 return 0; /* PT already derived */
224
225 ssid->pt = wpas_pasn_sae_derive_pt(ssid, group);
226
227 return ssid->pt ? 0 : -1;
228 }
229
230 #endif /* CONFIG_SAE */
231
232
wpas_pasn_get_group(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid,struct pasn_data * pasn)233 int wpas_pasn_get_group(struct wpa_supplicant *wpa_s,
234 struct wpa_ssid *ssid, struct pasn_data *pasn)
235 {
236 static const int default_groups[] = { 19, 20, 21, 0 };
237 const int *groups;
238 unsigned int i, j;
239
240 if (ssid && ssid->pasn_groups)
241 groups = ssid->pasn_groups;
242 else if (wpa_s->conf->pasn_groups)
243 groups = wpa_s->conf->pasn_groups;
244 else
245 groups = default_groups;
246
247 for (i = 0; groups[i]; i++) {
248 bool rejected = false;
249 bool ap_supported = true;
250
251 if (!dragonfly_suitable_group(groups[i], 1))
252 continue;
253
254 if (!pasn)
255 return groups[i];
256
257 /* Skip groups already rejected in this session */
258 for (j = 0; j < pasn->rejected_group_idx; j++) {
259 if (groups[i] == pasn->rejected_groups[j]) {
260 rejected = true;
261 break;
262 }
263 }
264 if (rejected)
265 continue;
266
267 /* Take intersection with AP's supported groups */
268 if (pasn->ap_supported_group_idx > 0) {
269 ap_supported = false;
270 for (j = 0; j < pasn->ap_supported_group_idx; j++) {
271 if (groups[i] == pasn->ap_supported_groups[j]) {
272 ap_supported = true;
273 break;
274 }
275 }
276 }
277 if (ap_supported)
278 return groups[i];
279 }
280
281 /* pasn_groups configured but no suitable group found - failure */
282 return 0;
283 }
284
285
wpas_pasn_get_params_from_bss(struct wpa_supplicant * wpa_s,struct pasn_peer * peer,struct wpa_bss * bss,struct wpa_ssid * ssid)286 static int wpas_pasn_get_params_from_bss(struct wpa_supplicant *wpa_s,
287 struct pasn_peer *peer,
288 struct wpa_bss *bss,
289 struct wpa_ssid *ssid)
290 {
291 int ret;
292 const u8 *rsne, *rsnxe;
293 struct wpa_ie_data rsne_data;
294 int sel, key_mgmt, pairwise_cipher;
295 int group;
296
297 group = wpas_pasn_get_group(wpa_s, ssid, NULL);
298
299 if (!group) {
300 wpa_printf(MSG_INFO,
301 "PASN: No suitable group found; cannot start authentication");
302 return -1;
303 }
304
305 wpa_printf(MSG_DEBUG, "PASN: Selected group %d", group);
306
307 rsne = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
308 if (!rsne) {
309 wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
310 return -1;
311 }
312
313 ret = wpa_parse_wpa_ie(rsne, *(rsne + 1) + 2, &rsne_data);
314 if (ret) {
315 wpa_printf(MSG_DEBUG, "PASN: Failed parsing RSNE data");
316 return -1;
317 }
318
319 rsnxe = wpa_bss_get_rsnxe(wpa_s, bss, NULL, false);
320
321
322 sel = rsne_data.pairwise_cipher;
323 if (peer->cipher && peer->cipher != WPA_CIPHER_NONE)
324 sel &= peer->cipher;
325 else if (ssid && !ssid->temporary && ssid->pairwise_cipher)
326 sel &= ssid->pairwise_cipher;
327
328 wpa_printf(MSG_DEBUG, "PASN: peer pairwise 0x%x, select 0x%x",
329 rsne_data.pairwise_cipher, sel);
330
331 pairwise_cipher = wpa_pick_pairwise_cipher(sel, 1);
332 if (pairwise_cipher < 0) {
333 wpa_msg(wpa_s, MSG_WARNING,
334 "PASN: Failed to select pairwise cipher");
335 return -1;
336 }
337
338 sel = rsne_data.key_mgmt;
339 if (peer->akmp && peer->akmp != WPA_KEY_MGMT_NONE)
340 sel &= peer->akmp;
341 else if (ssid && !ssid->temporary && ssid->key_mgmt)
342 sel &= ssid->key_mgmt;
343
344 wpa_printf(MSG_DEBUG, "PASN: peer AKMP 0x%x, select 0x%x",
345 rsne_data.key_mgmt, sel);
346 #ifdef CONFIG_SAE
347 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE) || !ssid)
348 sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_SAE_EXT_KEY |
349 WPA_KEY_MGMT_FT_SAE | WPA_KEY_MGMT_FT_SAE_EXT_KEY);
350 #endif /* CONFIG_SAE */
351 #ifdef CONFIG_IEEE80211R
352 if (!(wpa_s->drv_flags & (WPA_DRIVER_FLAGS_SME |
353 WPA_DRIVER_FLAGS_UPDATE_FT_IES)))
354 sel &= ~WPA_KEY_MGMT_FT;
355 #endif /* CONFIG_IEEE80211R */
356 if (0) {
357 #ifdef CONFIG_IEEE80211R
358 #ifdef CONFIG_SHA384
359 } else if ((sel & WPA_KEY_MGMT_FT_IEEE8021X_SHA384) &&
360 os_strcmp(wpa_supplicant_get_eap_mode(wpa_s), "LEAP") != 0) {
361 key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
362 wpa_printf(MSG_DEBUG, "PASN: using KEY_MGMT FT/802.1X-SHA384");
363 if (ssid && !ssid->ft_eap_pmksa_caching &&
364 pmksa_cache_get_current(wpa_s->wpa)) {
365 /* PMKSA caching with FT may have interoperability
366 * issues, so disable that case by default for now.
367 */
368 wpa_printf(MSG_DEBUG,
369 "PASN: Disable PMKSA caching for FT/802.1X connection");
370 pmksa_cache_clear_current(wpa_s->wpa);
371 }
372 #endif /* CONFIG_SHA384 */
373 #endif /* CONFIG_IEEE80211R */
374 #ifdef CONFIG_SAE
375 } else if ((sel & WPA_KEY_MGMT_SAE_EXT_KEY) && ssid &&
376 (ieee802_11_rsnx_capab(rsnxe,
377 WLAN_RSNX_CAPAB_SAE_H2E)) &&
378 (wpas_pasn_sae_setup_pt(ssid, group) == 0)) {
379 key_mgmt = WPA_KEY_MGMT_SAE_EXT_KEY;
380 wpa_printf(MSG_DEBUG, "PASN: using KEY_MGMT SAE (ext key)");
381 } else if ((sel & WPA_KEY_MGMT_SAE) && ssid &&
382 (ieee802_11_rsnx_capab(rsnxe,
383 WLAN_RSNX_CAPAB_SAE_H2E)) &&
384 (wpas_pasn_sae_setup_pt(ssid, group) == 0)) {
385 key_mgmt = WPA_KEY_MGMT_SAE;
386 wpa_printf(MSG_DEBUG, "PASN: using KEY_MGMT SAE");
387 #endif /* CONFIG_SAE */
388 #ifdef CONFIG_FILS
389 } else if (sel & WPA_KEY_MGMT_FILS_SHA384) {
390 key_mgmt = WPA_KEY_MGMT_FILS_SHA384;
391 wpa_printf(MSG_DEBUG, "PASN: using KEY_MGMT FILS-SHA384");
392 } else if (sel & WPA_KEY_MGMT_FILS_SHA256) {
393 key_mgmt = WPA_KEY_MGMT_FILS_SHA256;
394 wpa_printf(MSG_DEBUG, "PASN: using KEY_MGMT FILS-SHA256");
395 #endif /* CONFIG_FILS */
396 #ifdef CONFIG_IEEE80211R
397 } else if ((sel & WPA_KEY_MGMT_FT_IEEE8021X) &&
398 os_strcmp(wpa_supplicant_get_eap_mode(wpa_s), "LEAP") != 0) {
399 key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
400 wpa_printf(MSG_DEBUG, "PASN: using KEY_MGMT FT/802.1X");
401 if (ssid && !ssid->ft_eap_pmksa_caching &&
402 pmksa_cache_get_current(wpa_s->wpa)) {
403 /* PMKSA caching with FT may have interoperability
404 * issues, so disable that case by default for now.
405 */
406 wpa_printf(MSG_DEBUG,
407 "PASN: Disable PMKSA caching for FT/802.1X connection");
408 pmksa_cache_clear_current(wpa_s->wpa);
409 }
410 } else if (sel & WPA_KEY_MGMT_FT_PSK) {
411 key_mgmt = WPA_KEY_MGMT_FT_PSK;
412 wpa_printf(MSG_DEBUG, "PASN: using KEY_MGMT FT/PSK");
413 #endif /* CONFIG_IEEE80211R */
414 } else if (sel & WPA_KEY_MGMT_PASN) {
415 key_mgmt = WPA_KEY_MGMT_PASN;
416 wpa_printf(MSG_DEBUG, "PASN: using KEY_MGMT PASN");
417 } else {
418 wpa_printf(MSG_DEBUG, "PASN: invalid AKMP");
419 return -1;
420 }
421
422 peer->akmp = key_mgmt;
423 peer->cipher = pairwise_cipher;
424 if (ssid)
425 peer->network_id = ssid->id;
426 peer->group = group;
427 return 0;
428 }
429
430
wpas_pasn_set_keys_from_cache(struct wpa_supplicant * wpa_s,const u8 * own_addr,const u8 * peer_addr,int cipher,int akmp)431 static int wpas_pasn_set_keys_from_cache(struct wpa_supplicant *wpa_s,
432 const u8 *own_addr,
433 const u8 *peer_addr,
434 int cipher, int akmp)
435 {
436 struct ptksa_cache_entry *entry;
437
438 entry = ptksa_cache_get(wpa_s->ptksa, peer_addr, cipher);
439 if (!entry) {
440 wpa_printf(MSG_DEBUG, "PASN: peer " MACSTR
441 " not present in PTKSA cache", MAC2STR(peer_addr));
442 return -1;
443 }
444
445 if (!ether_addr_equal(entry->own_addr, own_addr)) {
446 wpa_printf(MSG_DEBUG,
447 "PASN: own addr " MACSTR " and PTKSA entry own addr "
448 MACSTR " differ",
449 MAC2STR(own_addr), MAC2STR(entry->own_addr));
450 return -1;
451 }
452
453 wpa_printf(MSG_DEBUG, "PASN: " MACSTR " present in PTKSA cache",
454 MAC2STR(peer_addr));
455 wpa_drv_set_secure_ranging_ctx(wpa_s, own_addr, peer_addr, cipher,
456 entry->ptk.tk_len,
457 entry->ptk.tk,
458 entry->ptk.ltf_keyseed_len,
459 entry->ptk.ltf_keyseed, 0);
460 return 0;
461 }
462
463
464 static struct wpa_ssid *
wpas_pasn_add_temporary_network(struct wpa_supplicant * wpa_s,const struct wpa_bss * bss,const char * password)465 wpas_pasn_add_temporary_network(struct wpa_supplicant *wpa_s,
466 const struct wpa_bss *bss, const char *password)
467 {
468 struct wpa_ssid *ssid;
469
470 ssid = wpa_config_add_network(wpa_s->conf);
471 if (!ssid) {
472 wpa_printf(MSG_DEBUG, "PASN: Failed to allocate SSID block");
473 return NULL;
474 }
475
476 ssid->ssid = os_memdup(bss->ssid, bss->ssid_len);
477 if (!ssid->ssid)
478 return NULL;
479
480 ssid->ssid_len = bss->ssid_len;
481 ssid->passphrase = os_strdup(password);
482 if (!ssid->passphrase) {
483 wpa_config_free_ssid(ssid);
484 wpa_printf(MSG_DEBUG, "PASN: Failed to copy password");
485 return NULL;
486 }
487
488 ssid->temporary = true;
489 wpa_printf(MSG_DEBUG, "PASN: Created temporary network block for "
490 MACSTR, MAC2STR(bss->bssid));
491
492 return ssid;
493 }
494
495
wpas_pasn_get_bss(struct wpa_supplicant * wpa_s,const u8 * peer_addr)496 static struct wpa_bss * wpas_pasn_get_bss(struct wpa_supplicant *wpa_s,
497 const u8 *peer_addr)
498 {
499 struct wpa_bss *bss;
500
501 bss = wpa_bss_get_bssid(wpa_s, peer_addr);
502 if (!bss) {
503 wpa_supplicant_update_scan_results(wpa_s, peer_addr);
504 bss = wpa_bss_get_bssid(wpa_s, peer_addr);
505 }
506
507 return bss;
508 }
509
510
wpas_pasn_get_network(struct wpa_supplicant * wpa_s,struct wpa_bss * bss)511 static struct wpa_ssid * wpas_pasn_get_network(struct wpa_supplicant *wpa_s,
512 struct wpa_bss *bss)
513 {
514 size_t ssid_str_len;
515 const u8 *ssid_str;
516 struct wpa_ssid *ssid;
517
518 ssid_str_len = bss->ssid_len;
519 ssid_str = bss->ssid;
520
521 /* Get the network configuration based on the obtained SSID */
522 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
523 if (ssid_str_len == ssid->ssid_len &&
524 os_memcmp(ssid_str, ssid->ssid, ssid_str_len) == 0)
525 break;
526 }
527
528 return ssid;
529 }
530
531
wpas_pasn_configure_next_peer(struct wpa_supplicant * wpa_s,struct pasn_auth * pasn_params)532 static void wpas_pasn_configure_next_peer(struct wpa_supplicant *wpa_s,
533 struct pasn_auth *pasn_params)
534 {
535 struct pasn_peer *peer;
536 struct wpa_ssid *ssid;
537
538 if (!pasn_params)
539 return;
540
541 while (wpa_s->pasn_count < pasn_params->num_peers) {
542 struct wpa_bss *bss;
543 bool check_cache = true;
544
545 peer = &pasn_params->peer[wpa_s->pasn_count];
546
547 if (ether_addr_equal(wpa_s->bssid, peer->peer_addr)) {
548 wpa_printf(MSG_DEBUG,
549 "PASN: Associated peer is not expected");
550 peer->status = PASN_STATUS_FAILURE;
551 wpa_s->pasn_count++;
552 continue;
553 }
554
555 bss = wpas_pasn_get_bss(wpa_s, peer->peer_addr);
556 if (!bss) {
557 wpa_printf(MSG_DEBUG, "PASN: BSS not found");
558 peer->status = PASN_STATUS_FAILURE;
559 wpa_s->pasn_count++;
560 continue;
561 }
562
563 ssid = wpas_pasn_get_network(wpa_s, bss);
564 if (peer->password && peer->akmp &&
565 peer->akmp != WPA_KEY_MGMT_NONE) {
566 ssid = wpas_pasn_add_temporary_network(wpa_s, bss,
567 peer->password);
568
569 if (!ssid) {
570 wpa_printf(MSG_DEBUG,
571 "PASN: Failed to create temporary network");
572 return;
573 }
574 peer->temporary_network = true;
575 }
576
577 if (ssid && ssid->temporary)
578 check_cache = false;
579
580 if (wpas_pasn_get_params_from_bss(wpa_s, peer, bss, ssid)) {
581 peer->status = PASN_STATUS_FAILURE;
582 wpa_s->pasn_count++;
583 continue;
584 }
585
586 if (check_cache &&
587 wpas_pasn_set_keys_from_cache(wpa_s, peer->own_addr,
588 peer->peer_addr,
589 peer->cipher,
590 peer->akmp) == 0) {
591 peer->status = PASN_STATUS_SUCCESS;
592 wpa_s->pasn_count++;
593 continue;
594 }
595
596 if (wpas_pasn_auth_start(wpa_s, peer->own_addr,
597 peer->peer_addr, peer->akmp,
598 peer->cipher, peer->group,
599 peer->network_id,
600 peer->comeback, peer->comeback_len,
601 WLAN_AUTH_PASN, 0, 0, 0, NULL,
602 false)) {
603 peer->status = PASN_STATUS_FAILURE;
604 wpa_msg(wpa_s, MSG_INFO, PASN_AUTH_STATUS MACSTR
605 " akmp=%s, status=%u",
606 MAC2STR(peer->peer_addr),
607 wpa_key_mgmt_txt(peer->akmp, WPA_PROTO_RSN),
608 peer->status);
609 wpa_s->pasn_count++;
610 wpas_pasn_free_peer(peer);
611 continue;
612 }
613 wpa_printf(MSG_DEBUG, "PASN: Sent PASN auth start for " MACSTR,
614 MAC2STR(peer->peer_addr));
615 return;
616 }
617
618 if (wpa_s->pasn_count == pasn_params->num_peers) {
619 unsigned int i;
620
621 wpa_drv_send_pasn_resp(wpa_s, pasn_params);
622 wpa_printf(MSG_DEBUG, "PASN: Response sent");
623 for (i = 0; i < pasn_params->num_peers; i++) {
624 peer = &pasn_params->peer[i];
625 wpas_pasn_free_peer(peer);
626
627 if (peer->temporary_network) {
628 ssid = wpa_config_get_network(wpa_s->conf,
629 peer->network_id);
630
631 if (ssid && ssid->temporary) {
632 wpa_config_remove_network(
633 wpa_s->conf, peer->network_id);
634 wpa_printf(MSG_DEBUG,
635 "PASN: Remove temporary network block of "
636 MACSTR, MAC2STR(peer->peer_addr));
637 }
638 }
639 }
640 os_free(wpa_s->pasn_params);
641 wpa_s->pasn_params = NULL;
642 }
643 }
644
645
wpas_pasn_auth_work_done(struct wpa_supplicant * wpa_s,int status)646 void wpas_pasn_auth_work_done(struct wpa_supplicant *wpa_s, int status)
647 {
648 if (!wpa_s->pasn_params)
649 return;
650
651 wpa_s->pasn_params->peer[wpa_s->pasn_count].status = status;
652 wpa_s->pasn_count++;
653 wpas_pasn_configure_next_peer(wpa_s, wpa_s->pasn_params);
654 }
655
656
wpas_pasn_delete_peers(struct wpa_supplicant * wpa_s,struct pasn_auth * pasn_params)657 static void wpas_pasn_delete_peers(struct wpa_supplicant *wpa_s,
658 struct pasn_auth *pasn_params)
659 {
660 struct pasn_peer *peer;
661 unsigned int i;
662
663 if (!pasn_params)
664 return;
665
666 for (i = 0; i < pasn_params->num_peers; i++) {
667 peer = &pasn_params->peer[i];
668 ptksa_cache_flush(wpa_s->ptksa, peer->peer_addr,
669 WPA_CIPHER_NONE);
670 wpas_pasn_free_peer_password(peer);
671 }
672 }
673
674
675 #ifdef CONFIG_FILS
wpas_pasn_initiate_eapol(struct pasn_data * pasn,struct wpa_ssid * ssid)676 static void wpas_pasn_initiate_eapol(struct pasn_data *pasn,
677 struct wpa_ssid *ssid)
678 {
679 struct eapol_config eapol_conf;
680
681 wpa_printf(MSG_DEBUG, "PASN: FILS: Initiating EAPOL");
682
683 eapol_sm_notify_eap_success(pasn->eapol, false);
684 eapol_sm_notify_eap_fail(pasn->eapol, false);
685 eapol_sm_notify_portControl(pasn->eapol, Auto);
686
687 os_memset(&eapol_conf, 0, sizeof(eapol_conf));
688 eapol_conf.fast_reauth = pasn->fast_reauth;
689 eapol_conf.workaround = ssid->eap_workaround;
690
691 eapol_sm_notify_config(pasn->eapol, &ssid->eap, &eapol_conf);
692 }
693 #endif /* CONFIG_FILS */
694
695
wpas_pasn_reset(struct wpa_supplicant * wpa_s)696 static void wpas_pasn_reset(struct wpa_supplicant *wpa_s)
697 {
698 struct pasn_data *pasn = &wpa_s->pasn;
699
700 wpas_pasn_cancel_auth_work(wpa_s);
701 wpa_s->pasn_auth_work = NULL;
702 eloop_cancel_timeout(wpas_pasn_auth_work_timeout, wpa_s, NULL);
703
704 wpa_pasn_reset(pasn);
705 }
706
707
wpas_pasn_allowed(struct wpa_supplicant * wpa_s,const u8 * peer_addr,int akmp,int cipher,int auth_alg,int group_cipher,int group_mgmt_cipher)708 static struct wpa_bss * wpas_pasn_allowed(struct wpa_supplicant *wpa_s,
709 const u8 *peer_addr, int akmp,
710 int cipher, int auth_alg,
711 int group_cipher,
712 int group_mgmt_cipher)
713 {
714 struct wpa_bss *bss;
715 const u8 *rsne;
716 struct wpa_ie_data rsne_data;
717 int ret;
718
719 if (auth_alg != WLAN_AUTH_EPPKE &&
720 ether_addr_equal(wpa_s->bssid, peer_addr)) {
721 wpa_printf(MSG_DEBUG,
722 "PASN: Not doing authentication with current BSS");
723 return NULL;
724 }
725
726 if (auth_alg == WLAN_AUTH_EPPKE) {
727 #if defined(CONFIG_SME) && defined(CONFIG_SAE)
728 /* EPPKE processing can reach here only when external
729 * authentication is used.
730 *
731 * In this flow, peer_addr is the peer MLD address for MLO.
732 * However, wpa_bss_get_bssid_latest() matches a link BSSID
733 * entry in the BSS table. Use the link BSSID saved by SME
734 * in ext_auth_bssid for BSS lookup.
735 */
736 bss = wpa_bss_get_bssid_latest(wpa_s,
737 wpa_s->sme.ext_auth_bssid);
738 #else /* CONFIG_SME && CONFIG_SAE */
739 wpa_printf(MSG_ERROR,
740 "EPPKE ext-auth requires CONFIG_SME and CONFIG_SAE");
741 return NULL;
742 #endif /* CONFIG_SME && CONFIG_SAE */
743 } else {
744 bss = wpa_bss_get_bssid_latest(wpa_s, peer_addr);
745 }
746 if (!bss) {
747 wpa_printf(MSG_DEBUG, "PASN: BSS not found");
748 return NULL;
749 }
750
751 rsne = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
752 if (!rsne) {
753 wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
754 return NULL;
755 }
756
757 ret = wpa_parse_wpa_ie(rsne, *(rsne + 1) + 2, &rsne_data);
758 if (ret) {
759 wpa_printf(MSG_DEBUG, "PASN: Failed parsing RSNE data");
760 return NULL;
761 }
762
763 if (!(rsne_data.key_mgmt & akmp) ||
764 !(rsne_data.pairwise_cipher & cipher)) {
765 wpa_printf(MSG_DEBUG,
766 "PASN: AP does not support requested AKMP or cipher");
767 return NULL;
768 }
769
770 #ifdef CONFIG_ENC_ASSOC
771 if (auth_alg == WLAN_AUTH_EPPKE) {
772 if (group_cipher &
773 !(rsne_data.group_cipher & group_cipher)) {
774 wpa_printf(MSG_DEBUG,
775 "EPPKE: AP does not support requested group cipher");
776 return NULL;
777 }
778 if (group_mgmt_cipher &&
779 !(rsne_data.mgmt_group_cipher & group_mgmt_cipher)) {
780 wpa_printf(MSG_DEBUG,
781 "EPPKE: AP does not support requested group mgmt cipher");
782 return NULL;
783 }
784 }
785 #endif /* CONFIG_ENC_ASSOC */
786
787 return bss;
788 }
789
790
791 #ifdef CONFIG_ENC_ASSOC
792 /*
793 * Build RSNE for EPPKE in SME-in-driver mode.
794 */
wpas_eppke_set_rsne(struct wpa_supplicant * wpa_s,struct pasn_data * pasn,struct wpa_pasn_auth_work * awork)795 static int wpas_eppke_set_rsne(struct wpa_supplicant *wpa_s,
796 struct pasn_data *pasn,
797 struct wpa_pasn_auth_work *awork)
798 {
799 u8 rsne[257];
800 int rsne_len;
801
802 rsne_len = wpa_external_auth_add_rsne(rsne, sizeof(rsne),
803 awork->akmp, awork->cipher,
804 awork->group_cipher,
805 awork->group_mgmt_cipher,
806 awork->rsn_capab,
807 sme_get_ext_auth_pmkid(wpa_s));
808 if (rsne_len < 0) {
809 wpa_printf(MSG_DEBUG, "EPPKE: Failed to build RSNE");
810 return -1;
811 }
812
813 pasn_set_rsne(pasn, rsne);
814 if (!pasn->rsn_ie)
815 return -1;
816
817 wpa_printf(MSG_DEBUG,
818 "EPPKE: RSNE for ext-auth (group=0x%x mgmt=0x%x capab=0x%x)",
819 awork->group_cipher, awork->group_mgmt_cipher,
820 awork->rsn_capab);
821 return 0;
822 }
823 #endif /* CONFIG_ENC_ASSOC */
824
825
wpas_pasn_auth_start_cb(struct wpa_radio_work * work,int deinit)826 static void wpas_pasn_auth_start_cb(struct wpa_radio_work *work, int deinit)
827 {
828 struct wpa_supplicant *wpa_s = work->wpa_s;
829 struct wpa_pasn_auth_work *awork = work->ctx;
830 struct pasn_data *pasn = &wpa_s->pasn;
831 struct wpa_ssid *ssid;
832 struct wpa_bss *bss;
833 const u8 *rsne, *rsnxe;
834 #ifdef CONFIG_FILS
835 const u8 *indic;
836 u16 fils_info;
837 #endif /* CONFIG_FILS */
838 u64 capab = 0;
839 bool derive_kdk;
840 int ret;
841
842 wpa_printf(MSG_DEBUG, "PASN: auth_start_cb: deinit=%d", deinit);
843
844 if (deinit) {
845 if (work->started) {
846 eloop_cancel_timeout(wpas_pasn_auth_work_timeout,
847 wpa_s, NULL);
848 wpa_s->pasn_auth_work = NULL;
849 }
850
851 wpas_pasn_free_auth_work(awork);
852 return;
853 }
854
855 /*
856 * It is possible that by the time the callback is called, the PASN
857 * authentication is not allowed, e.g., a connection with the AP was
858 * established.
859 */
860 bss = wpas_pasn_allowed(wpa_s, awork->peer_addr, awork->akmp,
861 awork->cipher, awork->auth_alg,
862 awork->group_cipher,
863 awork->group_mgmt_cipher);
864 if (!bss) {
865 wpa_printf(MSG_DEBUG, "PASN: auth_start_cb: Not allowed");
866 goto fail;
867 }
868
869 rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
870 if (!rsne) {
871 wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
872 goto fail;
873 }
874
875 /* Use the RSNXOE, if it was included, for actual AP capability check */
876 rsnxe = wpa_bss_get_rsnxe(wpa_s, bss, NULL, false);
877
878 derive_kdk = (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF_STA) &&
879 ieee802_11_rsnx_capab(rsnxe,
880 WLAN_RSNX_CAPAB_SECURE_LTF);
881 #ifdef CONFIG_TESTING_OPTIONS
882 if (!derive_kdk)
883 derive_kdk = wpa_s->conf->force_kdk_derivation;
884 #endif /* CONFIG_TESTING_OPTIONS */
885 if (derive_kdk)
886 pasn_enable_kdk_derivation(pasn);
887 else
888 pasn_disable_kdk_derivation(pasn);
889
890 wpa_printf(MSG_DEBUG, "PASN: kdk_len=%zu", pasn->kdk_len);
891
892 if ((wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF_STA) &&
893 ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF))
894 pasn->secure_ltf = true;
895 else
896 pasn->secure_ltf = false;
897
898 #ifdef CONFIG_TESTING_OPTIONS
899 pasn->corrupt_mic = wpa_s->conf->pasn_corrupt_mic;
900 #endif /* CONFIG_TESTING_OPTIONS */
901
902 if (wpa_key_mgmt_sae(awork->akmp))
903 capab |= BIT(WLAN_RSNX_CAPAB_SAE_H2E);
904 if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF_STA)
905 capab |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF);
906 if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_RTT_STA)
907 capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT);
908 if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG_STA) {
909 /*
910 * URNM_MFPR_X20 is a subset of URNM_MFPR which excludes 20 MHz
911 * bandwidth from mandating protected Management frames. Set
912 * URNM_MFPR only when URNM_MFPR_X20 is not set.
913 */
914 if (wpa_s->disable_urnm_mfpr) {
915 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_URNM_MFPR, 0);
916 } else {
917 capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR);
918 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_URNM_MFPR, 1);
919 }
920 if (wpa_s->urnm_mfpr_x20) {
921 capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR_X20);
922 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_URNM_MFPR_X20,
923 1);
924 } else {
925 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_URNM_MFPR_X20,
926 0);
927 }
928 }
929 if ((wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SPP_AMSDU) &&
930 ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SPP_A_MSDU))
931 capab |= BIT(WLAN_RSNX_CAPAB_SPP_A_MSDU);
932 ssid = wpa_config_get_network(wpa_s->conf, awork->network_id);
933 #ifdef CONFIG_ENC_ASSOC
934 if (awork->auth_alg == WLAN_AUTH_EPPKE) {
935 if (!ssid) {
936 wpa_printf(MSG_DEBUG,
937 "EPPKE: No network profile found");
938 goto fail;
939 }
940 if (!ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_KEK_IN_PASN))
941 {
942 wpa_printf(MSG_INFO,
943 "EPPKE: KEK_IN_PASN not set in AP RSNXE");
944 goto fail;
945 }
946 if (!ieee802_11_rsnx_capab(rsnxe,
947 WLAN_RSNX_CAPAB_ASSOC_FRAME_ENCRYPTION)) {
948 wpa_printf(MSG_INFO,
949 "EPPKE: ASSOC_FRAME_ENCRYPTION not set in AP RSNXE");
950 goto fail;
951 }
952 if (awork->akmp == WPA_KEY_MGMT_EPPKE &&
953 !ieee802_11_rsnx_capab(rsnxe,
954 WLAN_RSNX_CAPAB_UNAUTH_EPPKE)) {
955 wpa_printf(MSG_DEBUG,
956 "EPPKE: AP does not support unauthenticated EPPKE");
957 goto fail;
958 }
959 if (wpa_s->drv_flags2 &
960 WPA_DRIVER_FLAGS2_ASSOCIATION_FRAME_ENCRYPTION) {
961 capab |= BIT(WLAN_RSNX_CAPAB_ASSOC_FRAME_ENCRYPTION);
962 capab |= BIT(WLAN_RSNX_CAPAB_KEK_IN_PASN);
963 pasn->derive_kek = true;
964 #ifdef CONFIG_SAE
965 /*
966 * Advertise support for changing SAE password
967 * identifiers if configured per network profile.
968 */
969 if (ssid && ssid->sae_password_id &&
970 ssid->sae_password_id_change &&
971 wpa_key_mgmt_sae_ext_key(awork->akmp)) {
972 capab |= BIT_ULL(
973 WLAN_RSNX_CAPAB_SAE_PW_ID_CHANGE);
974 wpa_sm_set_param(wpa_s->wpa,
975 WPA_PARAM_SAE_PW_ID_CHANGE, 1);
976 }
977 #endif /* CONFIG_SAE */
978 #ifdef CONFIG_PMKSA_PRIVACY
979 if ((wpa_s->drv_flags2 &
980 WPA_DRIVER_FLAGS2_PMKSA_PRIVACY) &&
981 ssid->pmksa_privacy &&
982 ieee802_11_rsnx_capab(
983 rsnxe,
984 WLAN_RSNX_CAPAB_PMKSA_CACHING_PRIVACY))
985 capab |= BIT(
986 WLAN_RSNX_CAPAB_PMKSA_CACHING_PRIVACY);
987 #endif /* CONFIG_PMKSA_PRIVACY */
988 }
989 }
990 #endif /* CONFIG_ENC_ASSOC */
991
992 pasn_set_rsnxe_caps(pasn, capab);
993 pasn_register_callbacks(pasn, wpa_s, wpas_pasn_send_mlme, NULL, NULL,
994 NULL);
995
996 #ifdef CONFIG_SAE
997 if (awork->akmp == WPA_KEY_MGMT_SAE ||
998 awork->akmp == WPA_KEY_MGMT_SAE_EXT_KEY) {
999 struct sae_pt *pt = NULL;
1000
1001 if (!ssid) {
1002 wpa_printf(MSG_DEBUG,
1003 "PASN: No network profile found for SAE");
1004 goto fail;
1005 }
1006 #ifdef CONFIG_ENC_ASSOC
1007 if (awork->auth_alg == WLAN_AUTH_EPPKE)
1008 pt = wpas_pasn_sae_derive_pt_for_eppke(ssid,
1009 awork->group);
1010 #endif /* CONFIG_ENC_ASSOC */
1011 if (awork->auth_alg != WLAN_AUTH_EPPKE)
1012 pt = wpas_pasn_sae_derive_pt(ssid, awork->group);
1013 pasn_set_pt(pasn, pt);
1014 if (!pasn->pt) {
1015 wpa_printf(MSG_DEBUG, "PASN: Failed to derive PT");
1016 goto fail;
1017 }
1018 pasn->network_id = ssid->id;
1019 }
1020 #endif /* CONFIG_SAE */
1021
1022 #ifdef CONFIG_FILS
1023 /* Prepare needed information for wpas_pasn_wd_fils_auth(). */
1024 if (awork->akmp == WPA_KEY_MGMT_FILS_SHA256 ||
1025 awork->akmp == WPA_KEY_MGMT_FILS_SHA384) {
1026 indic = wpa_bss_get_ie(bss, WLAN_EID_FILS_INDICATION);
1027 if (!ssid) {
1028 wpa_printf(MSG_DEBUG, "PASN: FILS: No network block");
1029 } else if (!indic || indic[1] < 2) {
1030 wpa_printf(MSG_DEBUG,
1031 "PASN: Missing FILS Indication IE");
1032 } else {
1033 fils_info = WPA_GET_LE16(indic + 2);
1034 if ((fils_info & BIT(9)) && ssid) {
1035 pasn->eapol = wpa_s->eapol;
1036 pasn->network_id = ssid->id;
1037 wpas_pasn_initiate_eapol(pasn, ssid);
1038 pasn->fils_eapol = true;
1039 } else {
1040 wpa_printf(MSG_DEBUG,
1041 "PASN: FILS auth without PFS not supported");
1042 }
1043 }
1044 pasn->fast_reauth = wpa_s->conf->fast_reauth;
1045 }
1046 #endif /* CONFIG_FILS */
1047
1048 pasn_set_initiator_pmksa(pasn, wpa_sm_get_pmksa_cache(wpa_s->wpa));
1049
1050 if (wpa_key_mgmt_ft(awork->akmp)) {
1051 #ifdef CONFIG_IEEE80211R
1052 ret = wpa_pasn_ft_derive_pmk_r1(wpa_s->wpa, awork->akmp,
1053 awork->peer_addr,
1054 pasn->pmk_r1,
1055 &pasn->pmk_r1_len,
1056 pasn->pmk_r1_name);
1057 if (ret) {
1058 wpa_printf(MSG_DEBUG,
1059 "PASN: FT: Failed to derive keys");
1060 goto fail;
1061 }
1062 #else /* CONFIG_IEEE80211R */
1063 goto fail;
1064 #endif /* CONFIG_IEEE80211R */
1065 }
1066
1067 #ifdef CONFIG_ENC_ASSOC
1068 pasn->auth_alg = awork->auth_alg;
1069 pasn->group_cipher = awork->group_cipher;
1070 pasn->group_mgmt_cipher = awork->group_mgmt_cipher;
1071 pasn->rsn_capab = awork->rsn_capab;
1072 pasn_set_rsnxe_ie(pasn, awork->rsnxe_data);
1073 pasn->is_ml_peer = awork->is_ml_peer;
1074 /*
1075 * Set network_ctx so the PMKSA entry is stored with the correct
1076 * network context for lookup on reconnection.
1077 */
1078 if (awork->auth_alg == WLAN_AUTH_EPPKE && ssid)
1079 pasn->network_ctx = ssid;
1080
1081 /* Build RSNE for EPPKE Authentication in SME-in-driver mode */
1082 if (awork->auth_alg == WLAN_AUTH_EPPKE &&
1083 wpas_eppke_set_rsne(wpa_s, pasn, awork) < 0) {
1084 wpa_printf(MSG_DEBUG, "EPPKE: Failed to configure RSNE");
1085 goto fail;
1086 }
1087 #endif /* CONFIG_ENC_ASSOC */
1088
1089 /* PASN has not been defined to be modified for RSN overriding, so use
1090 * the RSNE and RSNXE from the AP for PASN MIC calculation instead of
1091 * the RSNO elements, if any. */
1092 rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
1093
1094 ret = wpas_pasn_start(pasn, awork->own_addr, awork->peer_addr,
1095 awork->peer_addr, awork->akmp, awork->cipher,
1096 awork->group, bss->freq, rsne, *(rsne + 1) + 2,
1097 rsnxe, rsnxe ? *(rsnxe + 1) + 2 : 0,
1098 awork->comeback);
1099 if (ret) {
1100 wpa_printf(MSG_DEBUG,
1101 "PASN: Failed to start PASN authentication");
1102 goto fail;
1103 }
1104 eloop_register_timeout(2, 0, wpas_pasn_auth_work_timeout, wpa_s, NULL);
1105
1106 /* comeback token is no longer needed at this stage */
1107 wpabuf_free(awork->comeback);
1108 awork->comeback = NULL;
1109
1110 wpa_s->pasn_auth_work = work;
1111 return;
1112 fail:
1113 wpas_pasn_free_auth_work(awork);
1114 work->ctx = NULL;
1115 radio_work_done(work);
1116 }
1117
1118
wpas_pasn_auth_start(struct wpa_supplicant * wpa_s,const u8 * own_addr,const u8 * peer_addr,int akmp,int cipher,u16 group,int network_id,const u8 * comeback,size_t comeback_len,unsigned int auth_alg,int group_cipher,int group_mgmt_cipher,u16 rsn_capab,const u8 * rsnxe_data,bool is_ml_peer)1119 int wpas_pasn_auth_start(struct wpa_supplicant *wpa_s,
1120 const u8 *own_addr, const u8 *peer_addr,
1121 int akmp, int cipher, u16 group, int network_id,
1122 const u8 *comeback, size_t comeback_len,
1123 unsigned int auth_alg, int group_cipher,
1124 int group_mgmt_cipher, u16 rsn_capab,
1125 const u8 *rsnxe_data, bool is_ml_peer)
1126 {
1127 struct wpa_pasn_auth_work *awork;
1128 struct wpa_bss *bss;
1129
1130 wpa_printf(MSG_DEBUG, "PASN: Start: " MACSTR " akmp=0x%x, cipher=0x%x",
1131 MAC2STR(peer_addr), akmp, cipher);
1132
1133 /*
1134 * TODO: Consider modifying the offchannel logic to handle additional
1135 * Management frames other then Action frames. For now allow PASN only
1136 * with drivers that support off-channel TX.
1137 */
1138 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX)) {
1139 wpa_printf(MSG_DEBUG,
1140 "PASN: Driver does not support offchannel TX");
1141 return -1;
1142 }
1143
1144 if (radio_work_pending(wpa_s, "pasn-start-auth")) {
1145 wpa_printf(MSG_DEBUG,
1146 "PASN: send_auth: Work is already pending");
1147 return -1;
1148 }
1149
1150 if (wpa_s->pasn_auth_work) {
1151 wpa_printf(MSG_DEBUG, "PASN: send_auth: Already in progress");
1152 return -1;
1153 }
1154
1155 bss = wpas_pasn_allowed(wpa_s, peer_addr, akmp, cipher, auth_alg,
1156 group_cipher, group_mgmt_cipher);
1157 if (!bss)
1158 return -1;
1159
1160 wpas_pasn_reset(wpa_s);
1161
1162 awork = os_zalloc(sizeof(*awork));
1163 if (!awork)
1164 return -1;
1165
1166 os_memcpy(awork->own_addr, own_addr, ETH_ALEN);
1167 os_memcpy(awork->peer_addr, peer_addr, ETH_ALEN);
1168 awork->akmp = akmp;
1169 awork->cipher = cipher;
1170 awork->group = group;
1171 awork->network_id = network_id;
1172 awork->auth_alg = auth_alg;
1173 awork->group_cipher = group_cipher;
1174 awork->group_mgmt_cipher = group_mgmt_cipher;
1175 #ifdef CONFIG_ENC_ASSOC
1176 awork->rsn_capab = rsn_capab;
1177 awork->is_ml_peer = is_ml_peer;
1178
1179 if (rsnxe_data) {
1180 awork->rsnxe_data = os_memdup(rsnxe_data, 2 + rsnxe_data[1]);
1181 if (!awork->rsnxe_data) {
1182 wpas_pasn_free_auth_work(awork);
1183 return -1;
1184 }
1185 }
1186 #endif /* CONFIG_ENC_ASSOC */
1187
1188 if (comeback && comeback_len) {
1189 awork->comeback = wpabuf_alloc_copy(comeback, comeback_len);
1190 if (!awork->comeback) {
1191 wpas_pasn_free_auth_work(awork);
1192 return -1;
1193 }
1194 }
1195
1196 if (!radio_add_work(wpa_s, bss->freq, "pasn-start-auth", 1,
1197 wpas_pasn_auth_start_cb, awork)) {
1198 wpas_pasn_free_auth_work(awork);
1199 return -1;
1200 }
1201
1202 wpa_printf(MSG_DEBUG, "PASN: Auth work successfully added");
1203 return 0;
1204 }
1205
1206
wpas_pasn_auth_stop(struct wpa_supplicant * wpa_s)1207 void wpas_pasn_auth_stop(struct wpa_supplicant *wpa_s)
1208 {
1209 struct pasn_data *pasn = &wpa_s->pasn;
1210
1211 if (!wpa_s->pasn.ecdh)
1212 return;
1213
1214 wpa_printf(MSG_DEBUG, "PASN: Stopping authentication");
1215
1216 wpas_pasn_auth_status(wpa_s, pasn->peer_addr, pasn_get_akmp(pasn),
1217 pasn_get_cipher(pasn),
1218 pasn->status, pasn->comeback,
1219 pasn->comeback_after);
1220
1221 wpas_pasn_reset(wpa_s);
1222
1223 /* Reset rejected group state when authentication ends */
1224 pasn->rejected_group_idx = 0;
1225 os_memset(pasn->rejected_groups, 0, sizeof(pasn->rejected_groups));
1226 }
1227
1228
wpas_pasn_free_params(struct wpa_supplicant * wpa_s)1229 void wpas_pasn_free_params(struct wpa_supplicant *wpa_s)
1230 {
1231 unsigned int i;
1232
1233 if (!wpa_s->pasn_params)
1234 return;
1235
1236 for (i = 0; i < wpa_s->pasn_params->num_peers; i++)
1237 wpas_pasn_free_peer(&wpa_s->pasn_params->peer[i]);
1238
1239 os_free(wpa_s->pasn_params);
1240 wpa_s->pasn_params = NULL;
1241 }
1242
1243
wpas_pasn_immediate_retry(struct wpa_supplicant * wpa_s,struct pasn_data * pasn,struct wpa_pasn_params_data * params)1244 static int wpas_pasn_immediate_retry(struct wpa_supplicant *wpa_s,
1245 struct pasn_data *pasn,
1246 struct wpa_pasn_params_data *params)
1247 {
1248 int akmp = pasn_get_akmp(pasn);
1249 int cipher = pasn_get_cipher(pasn);
1250 u16 group = pasn->group;
1251 u8 own_addr[ETH_ALEN];
1252 u8 peer_addr[ETH_ALEN];
1253 int network_id;
1254 unsigned int auth_alg;
1255
1256 wpa_printf(MSG_DEBUG, "PASN: Immediate retry");
1257 os_memcpy(own_addr, pasn->own_addr, ETH_ALEN);
1258 os_memcpy(peer_addr, pasn->peer_addr, ETH_ALEN);
1259
1260 /* Hold network ID to avoid losing it in wpas_pasn_reset(). */
1261 network_id = pasn->network_id;
1262
1263 /*
1264 * Cache auth_alg before reset as wpas_pasn_reset() clears the pasn
1265 * struct. This path is shared with EPPKE, so without preserving it,
1266 * a group rejection retry would incorrectly restart with PASN instead
1267 * of EPPKE.
1268 */
1269 auth_alg = pasn->auth_alg;
1270
1271 wpas_pasn_reset(wpa_s);
1272
1273 return wpas_pasn_auth_start(wpa_s, own_addr, peer_addr, akmp, cipher,
1274 group, network_id, params->comeback,
1275 params->comeback_len, auth_alg,
1276 pasn->group_cipher,
1277 pasn->group_mgmt_cipher, pasn->rsn_capab,
1278 pasn->rsnxe_ie, pasn->is_ml_peer);
1279 }
1280
1281
wpas_pasn_retry_with_next_group(struct wpa_supplicant * wpa_s,struct pasn_data * pasn)1282 static int wpas_pasn_retry_with_next_group(struct wpa_supplicant *wpa_s,
1283 struct pasn_data *pasn)
1284 {
1285 struct wpa_pasn_params_data params;
1286 u16 next_group;
1287 struct wpa_ssid *ssid = NULL;
1288
1289 #ifdef CONFIG_ENC_ASSOC
1290 if (pasn->auth_alg == WLAN_AUTH_EPPKE)
1291 ssid = wpa_s->current_ssid;
1292 #endif /* CONFIG_ENC_ASSOC */
1293
1294 next_group = (u16) wpas_pasn_get_group(wpa_s, ssid, pasn);
1295 if (!next_group) {
1296 wpa_printf(MSG_DEBUG,
1297 "PASN: No more groups to try after rejection");
1298 return -1;
1299 }
1300
1301 wpa_printf(MSG_DEBUG, "PASN: Retrying with group %u after rejection",
1302 next_group);
1303
1304 pasn->group = next_group;
1305
1306 os_memset(¶ms, 0, sizeof(params));
1307 return wpas_pasn_immediate_retry(wpa_s, pasn, ¶ms);
1308 }
1309
1310
wpas_pasn_deauth_cb(struct ptksa_cache_entry * entry)1311 static void wpas_pasn_deauth_cb(struct ptksa_cache_entry *entry)
1312 {
1313 struct wpa_supplicant *wpa_s = entry->ctx;
1314 u8 own_addr[ETH_ALEN];
1315 u8 peer_addr[ETH_ALEN];
1316
1317 /* Use a copy of the addresses from the entry to avoid issues with the
1318 * entry getting freed during deauthentication processing. */
1319 os_memcpy(own_addr, entry->own_addr, ETH_ALEN);
1320 os_memcpy(peer_addr, entry->addr, ETH_ALEN);
1321 wpas_pasn_deauthenticate(wpa_s, own_addr, peer_addr);
1322 }
1323
1324
wpas_pasn_store_comeback_data(struct wpa_supplicant * wpa_s,const struct wpabuf * comeback,u16 comeback_after)1325 static void wpas_pasn_store_comeback_data(struct wpa_supplicant *wpa_s,
1326 const struct wpabuf *comeback,
1327 u16 comeback_after)
1328 {
1329 struct pasn_peer *peer;
1330
1331 if (!wpa_s->pasn_params)
1332 return;
1333
1334 peer = &wpa_s->pasn_params->peer[wpa_s->pasn_count];
1335 if (!peer)
1336 return;
1337
1338 wpas_pasn_free_peer_comeback(peer);
1339 peer->comeback = os_memdup(wpabuf_head(comeback), wpabuf_len(comeback));
1340 if (!peer->comeback) {
1341 wpa_printf(MSG_ERROR,
1342 "PASN: Mem alloc failed for comeback data");
1343 return;
1344 }
1345
1346 peer->comeback_len = wpabuf_len(comeback);
1347 peer->comeback_after = comeback_after;
1348 }
1349
1350
wpas_pasn_auth_rx(struct wpa_supplicant * wpa_s,const struct ieee80211_mgmt * mgmt,size_t len)1351 int wpas_pasn_auth_rx(struct wpa_supplicant *wpa_s,
1352 const struct ieee80211_mgmt *mgmt, size_t len)
1353 {
1354 struct pasn_data *pasn = &wpa_s->pasn;
1355 struct wpa_pasn_params_data pasn_data;
1356 int ret;
1357
1358 if (!wpa_s->pasn_auth_work)
1359 return -2;
1360
1361 wpabuf_free(pasn->frame);
1362 pasn->frame = NULL;
1363
1364 pasn_register_callbacks(pasn, wpa_s, wpas_pasn_send_mlme, NULL, NULL,
1365 NULL);
1366 ret = wpa_pasn_auth_rx(pasn, (const u8 *) mgmt, len, &pasn_data);
1367 if (ret == 0) {
1368 ptksa_cache_add(wpa_s->ptksa, pasn->own_addr, pasn->peer_addr,
1369 pasn_get_cipher(pasn),
1370 dot11RSNAConfigPMKLifetime,
1371 pasn_get_ptk(pasn),
1372 wpa_s->pasn_params ? wpas_pasn_deauth_cb : NULL,
1373 wpa_s->pasn_params ? wpa_s : NULL,
1374 pasn_get_akmp(pasn), pasn->auth_alg);
1375
1376 if (pasn->pmksa_entry)
1377 wpa_sm_set_cur_pmksa(wpa_s->wpa, pasn->pmksa_entry);
1378
1379 if (pasn->auth_alg == WLAN_AUTH_EPPKE) {
1380 #ifdef CONFIG_SME
1381 os_memcpy(wpa_s->sme.sae.pmkid, pasn->sae.pmkid,
1382 PMKID_LEN);
1383 #endif /* CONFIG_SME */
1384 wpa_sm_set_pmk(wpa_s->wpa, pasn->pmk, pasn->pmk_len,
1385 pasn->sae.pmkid, NULL);
1386 }
1387 }
1388
1389 forced_memzero(pasn_get_ptk(pasn), sizeof(pasn->ptk));
1390
1391 if (ret == -1) {
1392 if (pasn->status == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
1393 pasn->comeback && wpabuf_len(pasn->comeback))
1394 wpas_pasn_store_comeback_data(wpa_s, pasn->comeback,
1395 pasn->comeback_after);
1396 wpas_pasn_auth_stop(wpa_s);
1397 wpas_pasn_auth_work_done(wpa_s, PASN_STATUS_FAILURE);
1398 }
1399
1400 if (ret == 1)
1401 ret = wpas_pasn_immediate_retry(wpa_s, pasn, &pasn_data);
1402
1403 if (ret == 2) {
1404 ret = wpas_pasn_retry_with_next_group(wpa_s, pasn);
1405 if (ret) {
1406 wpa_printf(MSG_INFO,
1407 "PASN: Group rejection retry failed");
1408 wpas_pasn_auth_stop(wpa_s);
1409 wpas_pasn_auth_work_done(wpa_s, PASN_STATUS_FAILURE);
1410 }
1411 }
1412
1413 return ret;
1414 }
1415
1416
wpas_pasn_auth_trigger(struct wpa_supplicant * wpa_s,struct pasn_auth * pasn_auth)1417 void wpas_pasn_auth_trigger(struct wpa_supplicant *wpa_s,
1418 struct pasn_auth *pasn_auth)
1419 {
1420 struct pasn_peer *src, *dst;
1421 unsigned int i, num_peers = pasn_auth->num_peers;
1422
1423 if (wpa_s->pasn_params) {
1424 wpa_printf(MSG_DEBUG,
1425 "PASN: auth_trigger: Already in progress");
1426 return;
1427 }
1428
1429 if (!num_peers || num_peers > WPAS_MAX_PASN_PEERS) {
1430 wpa_printf(MSG_DEBUG,
1431 "PASN: auth trigger: Invalid number of peers");
1432 return;
1433 }
1434
1435 wpa_s->pasn_params = os_zalloc(sizeof(struct pasn_auth));
1436 if (!wpa_s->pasn_params) {
1437 wpa_printf(MSG_DEBUG,
1438 "PASN: auth trigger: Failed to allocate a buffer");
1439 return;
1440 }
1441
1442 wpa_s->pasn_count = 0;
1443 wpa_s->pasn_params->num_peers = num_peers;
1444
1445 for (i = 0; i < num_peers; i++) {
1446 dst = &wpa_s->pasn_params->peer[i];
1447 src = &pasn_auth->peer[i];
1448 os_memcpy(dst->own_addr, wpa_s->own_addr, ETH_ALEN);
1449 os_memcpy(dst->peer_addr, src->peer_addr, ETH_ALEN);
1450 dst->ltf_keyseed_required = src->ltf_keyseed_required;
1451 dst->status = PASN_STATUS_SUCCESS;
1452 dst->akmp = src->akmp;
1453 dst->cipher = src->cipher;
1454 if (src->password) {
1455 dst->password = os_strdup(src->password);
1456 if (!dst->password) {
1457 wpa_printf(MSG_DEBUG,
1458 "PASN: Mem alloc failed for password");
1459 goto fail;
1460 }
1461 }
1462 if (src->comeback_len && src->comeback) {
1463 dst->comeback = os_memdup(src->comeback,
1464 src->comeback_len);
1465 if (!dst->comeback) {
1466 wpa_printf(MSG_DEBUG,
1467 "PASN: Mem alloc failed for comeback cookie");
1468 goto fail;
1469 }
1470 dst->comeback_len = src->comeback_len;
1471 }
1472
1473 if (!is_zero_ether_addr(src->own_addr)) {
1474 os_memcpy(dst->own_addr, src->own_addr, ETH_ALEN);
1475 wpa_printf(MSG_DEBUG, "PASN: Own (source) MAC addr: "
1476 MACSTR, MAC2STR(dst->own_addr));
1477 }
1478 }
1479
1480 if (pasn_auth->action == PASN_ACTION_DELETE_SECURE_RANGING_CONTEXT) {
1481 wpas_pasn_delete_peers(wpa_s, wpa_s->pasn_params);
1482 os_free(wpa_s->pasn_params);
1483 wpa_s->pasn_params = NULL;
1484 } else if (pasn_auth->action == PASN_ACTION_AUTH) {
1485 wpas_pasn_configure_next_peer(wpa_s, wpa_s->pasn_params);
1486 }
1487
1488 return;
1489
1490 fail:
1491 wpas_pasn_free_params(wpa_s);
1492 }
1493
1494
1495 #ifdef CONFIG_SME
1496 #ifdef CONFIG_ENC_ASSOC
wpas_eppke_external_auth_set_keys(struct wpa_supplicant * wpa_s,struct pasn_data * pasn,bool acked)1497 static u16 wpas_eppke_external_auth_set_keys(struct wpa_supplicant *wpa_s,
1498 struct pasn_data *pasn, bool acked)
1499 {
1500 static const u8 zero[WPA_TK_MAX_LEN] = { 0 };
1501 enum wpa_alg alg;
1502 struct ptksa_cache_entry *entry;
1503
1504 if (!acked) {
1505 wpa_printf(MSG_DEBUG,
1506 "EPPKE: Authentication frame 3 TX was not ACKed");
1507 return WLAN_STATUS_UNSPECIFIED_FAILURE;
1508 }
1509
1510 alg = wpa_cipher_to_alg(pasn_get_cipher(pasn));
1511 entry = ptksa_cache_get(wpa_s->ptksa, pasn->peer_addr,
1512 pasn_get_cipher(pasn));
1513 if (!entry) {
1514 wpa_printf(MSG_INFO,
1515 "EPPKE: No PTKSA found to configure keys");
1516 return WLAN_STATUS_UNSPECIFIED_FAILURE;
1517 }
1518
1519 /* Install TK to driver. */
1520 if (wpa_drv_set_key(wpa_s, -1, alg, pasn->peer_addr, 0, 1, zero, 6,
1521 entry->ptk.tk, entry->ptk.tk_len,
1522 KEY_FLAG_PAIRWISE_RX_TX)) {
1523 wpa_printf(MSG_DEBUG,
1524 "EPPKE: Failed to install TK to driver");
1525 return WLAN_STATUS_UNSPECIFIED_FAILURE;
1526 }
1527
1528 /* Install LTF Keyseed to driver. */
1529 if (pasn->secure_ltf &&
1530 wpa_drv_set_secure_ranging_ctx(wpa_s, pasn->own_addr,
1531 pasn->peer_addr,
1532 pasn_get_cipher(pasn), 0, NULL,
1533 entry->ptk.ltf_keyseed_len,
1534 entry->ptk.ltf_keyseed, 0)) {
1535 wpa_printf(MSG_DEBUG,
1536 "EPPKE: Failed to install LTF Keyseed");
1537 return WLAN_STATUS_UNSPECIFIED_FAILURE;
1538 }
1539
1540 return WLAN_STATUS_SUCCESS;
1541 }
1542 #endif /* CONFIG_ENC_ASSOC */
1543 #endif /* CONFIG_SME */
1544
1545
wpas_pasn_auth_tx_status(struct wpa_supplicant * wpa_s,const u8 * data,size_t data_len,u8 acked)1546 int wpas_pasn_auth_tx_status(struct wpa_supplicant *wpa_s,
1547 const u8 *data, size_t data_len, u8 acked)
1548
1549 {
1550 struct pasn_data *pasn = &wpa_s->pasn;
1551 int ret;
1552 enum pasn_status auth_status = PASN_STATUS_SUCCESS;
1553
1554 if (!wpa_s->pasn_auth_work) {
1555 wpa_printf(MSG_DEBUG,
1556 "PASN: auth_tx_status: no work in progress");
1557 return -1;
1558 }
1559
1560 ret = wpa_pasn_auth_tx_status(pasn, data, data_len, acked);
1561 if (ret != 1)
1562 return ret;
1563
1564 if (pasn->auth_alg == WLAN_AUTH_EPPKE) {
1565 #ifdef CONFIG_SME
1566 #ifdef CONFIG_ENC_ASSOC
1567 u16 status;
1568
1569 status = wpas_eppke_external_auth_set_keys(wpa_s, pasn, acked);
1570 if (status != WLAN_STATUS_SUCCESS)
1571 auth_status = PASN_STATUS_FAILURE;
1572 #ifdef CONFIG_SAE
1573 sme_send_external_auth_status(wpa_s, status);
1574 #endif /* CONFIG_SAE */
1575 #endif /* CONFIG_ENC_ASSOC */
1576 #endif /* CONFIG_SME */
1577 goto auth_done;
1578 }
1579
1580 if (!wpa_s->pasn_params) {
1581 wpas_pasn_auth_stop(wpa_s);
1582 return 0;
1583 }
1584
1585 wpas_pasn_set_keys_from_cache(wpa_s, pasn->own_addr, pasn->peer_addr,
1586 pasn_get_cipher(pasn),
1587 pasn_get_akmp(pasn));
1588 auth_done:
1589 wpas_pasn_auth_stop(wpa_s);
1590 wpas_pasn_auth_work_done(wpa_s, auth_status);
1591
1592 return 0;
1593 }
1594
1595
wpas_pasn_deauthenticate(struct wpa_supplicant * wpa_s,const u8 * own_addr,const u8 * peer_addr)1596 int wpas_pasn_deauthenticate(struct wpa_supplicant *wpa_s, const u8 *own_addr,
1597 const u8 *peer_addr)
1598 {
1599 struct wpa_bss *bss;
1600 struct wpabuf *buf;
1601 struct ieee80211_mgmt *deauth;
1602 int ret;
1603
1604 if (ether_addr_equal(wpa_s->bssid, peer_addr)) {
1605 wpa_printf(MSG_DEBUG,
1606 "PASN: Cannot deauthenticate from current BSS");
1607 return -1;
1608 }
1609
1610 wpa_drv_set_secure_ranging_ctx(wpa_s, own_addr, peer_addr, 0, 0, NULL,
1611 0, NULL, 1);
1612
1613 wpa_printf(MSG_DEBUG, "PASN: deauth: Flushing all PTKSA entries for "
1614 MACSTR, MAC2STR(peer_addr));
1615 ptksa_cache_flush(wpa_s->ptksa, peer_addr, WPA_CIPHER_NONE);
1616
1617 bss = wpa_bss_get_bssid(wpa_s, peer_addr);
1618 if (!bss) {
1619 wpa_printf(MSG_DEBUG, "PASN: deauth: BSS not found");
1620 return -1;
1621 }
1622
1623 buf = wpabuf_alloc(64);
1624 if (!buf) {
1625 wpa_printf(MSG_DEBUG, "PASN: deauth: Failed wpabuf allocate");
1626 return -1;
1627 }
1628
1629 deauth = wpabuf_put(buf, offsetof(struct ieee80211_mgmt,
1630 u.deauth.variable));
1631
1632 deauth->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
1633 (WLAN_FC_STYPE_DEAUTH << 4));
1634
1635 os_memcpy(deauth->da, peer_addr, ETH_ALEN);
1636 os_memcpy(deauth->sa, own_addr, ETH_ALEN);
1637 os_memcpy(deauth->bssid, peer_addr, ETH_ALEN);
1638 deauth->u.deauth.reason_code =
1639 host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
1640
1641 /*
1642 * Since we do not expect any response from the AP, implement the
1643 * Deauthentication frame transmission using direct call to the driver
1644 * without a radio work.
1645 */
1646 ret = wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1,
1647 bss->freq, 0);
1648
1649 wpabuf_free(buf);
1650 wpa_printf(MSG_DEBUG, "PASN: deauth: send_mlme ret=%d", ret);
1651
1652 return ret;
1653 }
1654