1 /*
2 * wpa_supplicant - PASN processing
3 *
4 * Copyright (C) 2019 Intel Corporation
5 *
6 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
8 */
9
10 #include "includes.h"
11
12 #include "common/ieee802_11_defs.h"
13 #include "common/ieee802_11_common.h"
14 #include "common/dragonfly.h"
15 #include "common/ptksa_cache.h"
16 #include "utils/eloop.h"
17 #include "drivers/driver.h"
18 #include "crypto/crypto.h"
19 #include "crypto/random.h"
20 #include "eap_common/eap_defs.h"
21 #include "rsn_supp/wpa.h"
22 #include "rsn_supp/pmksa_cache.h"
23 #include "wpa_supplicant_i.h"
24 #include "driver_i.h"
25 #include "bss.h"
26 #include "config.h"
27
28 static const int dot11RSNAConfigPMKLifetime = 43200;
29
30 struct wpa_pasn_auth_work {
31 u8 bssid[ETH_ALEN];
32 int akmp;
33 int cipher;
34 u16 group;
35 int network_id;
36 };
37
38
wpas_pasn_auth_work_timeout(void * eloop_ctx,void * timeout_ctx)39 static void wpas_pasn_auth_work_timeout(void *eloop_ctx, void *timeout_ctx)
40 {
41 struct wpa_supplicant *wpa_s = eloop_ctx;
42
43 wpa_printf(MSG_DEBUG, "PASN: Auth work timeout - stopping auth");
44
45 wpas_pasn_auth_stop(wpa_s);
46 }
47
48
wpas_pasn_cancel_auth_work(struct wpa_supplicant * wpa_s)49 static void wpas_pasn_cancel_auth_work(struct wpa_supplicant *wpa_s)
50 {
51 wpa_printf(MSG_DEBUG, "PASN: Cancel pasn-start-auth work");
52
53 /* Remove pending/started work */
54 radio_remove_works(wpa_s, "pasn-start-auth", 0);
55 }
56
57
wpas_pasn_auth_status(struct wpa_supplicant * wpa_s,const u8 * bssid,int akmp,int cipher,u8 status)58 static void wpas_pasn_auth_status(struct wpa_supplicant *wpa_s, const u8 *bssid,
59 int akmp, int cipher, u8 status)
60 {
61 wpa_msg(wpa_s, MSG_INFO,
62 PASN_AUTH_STATUS MACSTR " akmp=%s, status=%u",
63 MAC2STR(bssid), wpa_key_mgmt_txt(akmp, WPA_PROTO_RSN),
64 status);
65 }
66
67
68 #ifdef CONFIG_SAE
69
wpas_pasn_wd_sae_commit(struct wpa_supplicant * wpa_s)70 static struct wpabuf * wpas_pasn_wd_sae_commit(struct wpa_supplicant *wpa_s)
71 {
72 struct wpas_pasn *pasn = &wpa_s->pasn;
73 struct wpabuf *buf = NULL;
74 const char *password = NULL;
75 int ret;
76
77 if (pasn->ssid) {
78 password = pasn->ssid->sae_password;
79 if (!password)
80 password = pasn->ssid->passphrase;
81 }
82
83 if (!password) {
84 wpa_printf(MSG_DEBUG, "PASN: SAE without a password");
85 return NULL;
86 }
87
88 ret = sae_set_group(&pasn->sae, pasn->group);
89 if (ret) {
90 wpa_printf(MSG_DEBUG, "PASN: Failed to set SAE group");
91 return NULL;
92 }
93
94 /* TODO: SAE H2E */
95 ret = sae_prepare_commit(wpa_s->own_addr, pasn->bssid,
96 (const u8 *) password, os_strlen(password), 0,
97 &pasn->sae);
98 if (ret) {
99 wpa_printf(MSG_DEBUG, "PASN: Failed to prepare SAE commit");
100 return NULL;
101 }
102
103 /* Need to add the entire Authentication frame body */
104 buf = wpabuf_alloc(6 + SAE_COMMIT_MAX_LEN);
105 if (!buf) {
106 wpa_printf(MSG_DEBUG, "PASN: Failed to allocate SAE buffer");
107 return NULL;
108 }
109
110 wpabuf_put_le16(buf, WLAN_AUTH_SAE);
111 wpabuf_put_le16(buf, 1);
112 wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
113
114 sae_write_commit(&pasn->sae, buf, NULL, 0);
115 pasn->sae.state = SAE_COMMITTED;
116
117 return buf;
118 }
119
120
wpas_pasn_wd_sae_rx(struct wpa_supplicant * wpa_s,struct wpabuf * wd)121 static int wpas_pasn_wd_sae_rx(struct wpa_supplicant *wpa_s, struct wpabuf *wd)
122 {
123 struct wpas_pasn *pasn = &wpa_s->pasn;
124 const u8 *data;
125 size_t buf_len;
126 u16 len, res, alg, seq, status;
127 int groups[] = { pasn->group, 0 };
128 int ret;
129
130 if (!wd)
131 return -1;
132
133 data = wpabuf_head_u8(wd);
134 buf_len = wpabuf_len(wd);
135
136 /* first handle the commit message */
137 if (buf_len < 2) {
138 wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short (commit)");
139 return -1;
140 }
141
142 len = WPA_GET_LE16(data);
143 if (len < 6 || buf_len - 2 < len) {
144 wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short for commit");
145 return -1;
146 }
147
148 buf_len -= 2;
149 data += 2;
150
151 alg = WPA_GET_LE16(data);
152 seq = WPA_GET_LE16(data + 2);
153 status = WPA_GET_LE16(data + 4);
154
155 wpa_printf(MSG_DEBUG, "PASN: SAE: commit: alg=%u, seq=%u, status=%u",
156 alg, seq, status);
157
158 /* TODO: SAE H2E */
159 if (alg != WLAN_AUTH_SAE || seq != 1 || status != WLAN_STATUS_SUCCESS) {
160 wpa_printf(MSG_DEBUG, "PASN: SAE: dropping peer commit");
161 return -1;
162 }
163
164 res = sae_parse_commit(&pasn->sae, data + 6, len - 6, NULL, 0, groups,
165 0);
166 if (res != WLAN_STATUS_SUCCESS) {
167 wpa_printf(MSG_DEBUG, "PASN: SAE failed parsing commit");
168 return -1;
169 }
170
171 /* Process the commit message and derive the PMK */
172 ret = sae_process_commit(&pasn->sae);
173 if (ret) {
174 wpa_printf(MSG_DEBUG, "SAE: Failed to process peer commit");
175 return -1;
176 }
177
178 buf_len -= len;
179 data += len;
180
181 /* Handle the confirm message */
182 if (buf_len < 2) {
183 wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short (confirm)");
184 return -1;
185 }
186
187 len = WPA_GET_LE16(data);
188 if (len < 6 || buf_len - 2 < len) {
189 wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short for confirm");
190 return -1;
191 }
192
193 buf_len -= 2;
194 data += 2;
195
196 alg = WPA_GET_LE16(data);
197 seq = WPA_GET_LE16(data + 2);
198 status = WPA_GET_LE16(data + 4);
199
200 wpa_printf(MSG_DEBUG, "PASN: SAE confirm: alg=%u, seq=%u, status=%u",
201 alg, seq, status);
202
203 if (alg != WLAN_AUTH_SAE || seq != 2 || status != WLAN_STATUS_SUCCESS) {
204 wpa_printf(MSG_DEBUG, "PASN: Dropping peer SAE confirm");
205 return -1;
206 }
207
208 res = sae_check_confirm(&pasn->sae, data + 6, len - 6);
209 if (res != WLAN_STATUS_SUCCESS) {
210 wpa_printf(MSG_DEBUG, "PASN: SAE failed checking confirm");
211 return -1;
212 }
213
214 wpa_printf(MSG_DEBUG, "PASN: SAE completed successfully");
215 pasn->sae.state = SAE_ACCEPTED;
216
217 return 0;
218 }
219
220
wpas_pasn_wd_sae_confirm(struct wpa_supplicant * wpa_s)221 static struct wpabuf * wpas_pasn_wd_sae_confirm(struct wpa_supplicant *wpa_s)
222 {
223 struct wpas_pasn *pasn = &wpa_s->pasn;
224 struct wpabuf *buf = NULL;
225
226 /* Need to add the entire authentication frame body */
227 buf = wpabuf_alloc(6 + SAE_CONFIRM_MAX_LEN);
228 if (!buf) {
229 wpa_printf(MSG_DEBUG, "PASN: Failed to allocate SAE buffer");
230 return NULL;
231 }
232
233 wpabuf_put_le16(buf, WLAN_AUTH_SAE);
234 wpabuf_put_le16(buf, 2);
235 wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
236
237 sae_write_confirm(&pasn->sae, buf);
238 pasn->sae.state = SAE_CONFIRMED;
239
240 return buf;
241 }
242
243 #endif /* CONFIG_SAE */
244
245
246 #ifdef CONFIG_FILS
247
wpas_pasn_fils_build_auth(struct wpa_supplicant * wpa_s)248 static struct wpabuf * wpas_pasn_fils_build_auth(struct wpa_supplicant *wpa_s)
249 {
250 struct wpas_pasn *pasn = &wpa_s->pasn;
251 struct wpabuf *buf = NULL;
252 struct wpabuf *erp_msg;
253 int ret;
254
255 erp_msg = eapol_sm_build_erp_reauth_start(wpa_s->eapol);
256 if (!erp_msg) {
257 wpa_printf(MSG_DEBUG,
258 "PASN: FILS: ERP EAP-Initiate/Re-auth unavailable");
259 return NULL;
260 }
261
262 if (random_get_bytes(pasn->fils.nonce, FILS_NONCE_LEN) < 0 ||
263 random_get_bytes(pasn->fils.session, FILS_SESSION_LEN) < 0)
264 goto fail;
265
266 wpa_hexdump(MSG_DEBUG, "PASN: FILS: Nonce", pasn->fils.nonce,
267 FILS_NONCE_LEN);
268
269 wpa_hexdump(MSG_DEBUG, "PASN: FILS: Session", pasn->fils.session,
270 FILS_SESSION_LEN);
271
272 buf = wpabuf_alloc(1500);
273 if (!buf)
274 goto fail;
275
276 /* Add the authentication algorithm */
277 wpabuf_put_le16(buf, WLAN_AUTH_FILS_SK);
278
279 /* Authentication Transaction seq# */
280 wpabuf_put_le16(buf, 1);
281
282 /* Status Code */
283 wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
284
285 /* Own RSNE */
286 wpa_pasn_add_rsne(buf, NULL, pasn->akmp, pasn->cipher);
287
288 /* FILS Nonce */
289 wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
290 wpabuf_put_u8(buf, 1 + FILS_NONCE_LEN);
291 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_NONCE);
292 wpabuf_put_data(buf, pasn->fils.nonce, FILS_NONCE_LEN);
293
294 /* FILS Session */
295 wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
296 wpabuf_put_u8(buf, 1 + FILS_SESSION_LEN);
297 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_SESSION);
298 wpabuf_put_data(buf, pasn->fils.session, FILS_SESSION_LEN);
299
300 /* Wrapped Data (ERP) */
301 wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
302 wpabuf_put_u8(buf, 1 + wpabuf_len(erp_msg));
303 wpabuf_put_u8(buf, WLAN_EID_EXT_WRAPPED_DATA);
304 wpabuf_put_buf(buf, erp_msg);
305
306 /*
307 * Calculate pending PMKID here so that we do not need to maintain a
308 * copy of the EAP-Initiate/Reauth message.
309 */
310 ret = fils_pmkid_erp(pasn->akmp, wpabuf_head(erp_msg),
311 wpabuf_len(erp_msg),
312 pasn->fils.erp_pmkid);
313 if (ret) {
314 wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to get ERP PMKID");
315 goto fail;
316 }
317
318 wpabuf_free(erp_msg);
319 erp_msg = NULL;
320
321 wpa_hexdump_buf(MSG_DEBUG, "PASN: FILS: Authentication frame", buf);
322 return buf;
323 fail:
324 wpabuf_free(erp_msg);
325 wpabuf_free(buf);
326 return NULL;
327 }
328
329
wpas_pasn_initiate_eapol(struct wpa_supplicant * wpa_s)330 static void wpas_pasn_initiate_eapol(struct wpa_supplicant *wpa_s)
331 {
332 struct wpas_pasn *pasn = &wpa_s->pasn;
333 struct eapol_config eapol_conf;
334 struct wpa_ssid *ssid = pasn->ssid;
335
336 wpa_printf(MSG_DEBUG, "PASN: FILS: Initiating EAPOL");
337
338 eapol_sm_notify_eap_success(wpa_s->eapol, false);
339 eapol_sm_notify_eap_fail(wpa_s->eapol, false);
340 eapol_sm_notify_portControl(wpa_s->eapol, Auto);
341
342 os_memset(&eapol_conf, 0, sizeof(eapol_conf));
343 eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
344 eapol_conf.workaround = ssid->eap_workaround;
345
346 eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
347 }
348
349
wpas_pasn_wd_fils_auth(struct wpa_supplicant * wpa_s)350 static struct wpabuf * wpas_pasn_wd_fils_auth(struct wpa_supplicant *wpa_s)
351 {
352 struct wpas_pasn *pasn = &wpa_s->pasn;
353 struct wpa_bss *bss;
354 const u8 *indic;
355 u16 fils_info;
356
357 wpa_printf(MSG_DEBUG, "PASN: FILS: wrapped data - completed=%u",
358 pasn->fils.completed);
359
360 /* Nothing to add as we are done */
361 if (pasn->fils.completed)
362 return NULL;
363
364 if (!pasn->ssid) {
365 wpa_printf(MSG_DEBUG, "PASN: FILS: No network block");
366 return NULL;
367 }
368
369 bss = wpa_bss_get_bssid(wpa_s, pasn->bssid);
370 if (!bss) {
371 wpa_printf(MSG_DEBUG, "PASN: FILS: BSS not found");
372 return NULL;
373 }
374
375 indic = wpa_bss_get_ie(bss, WLAN_EID_FILS_INDICATION);
376 if (!indic || indic[1] < 2) {
377 wpa_printf(MSG_DEBUG, "PASN: Missing FILS Indication IE");
378 return NULL;
379 }
380
381 fils_info = WPA_GET_LE16(indic + 2);
382 if (!(fils_info & BIT(9))) {
383 wpa_printf(MSG_DEBUG,
384 "PASN: FILS auth without PFS not supported");
385 return NULL;
386 }
387
388 wpas_pasn_initiate_eapol(wpa_s);
389
390 return wpas_pasn_fils_build_auth(wpa_s);
391 }
392
393
wpas_pasn_wd_fils_rx(struct wpa_supplicant * wpa_s,struct wpabuf * wd)394 static int wpas_pasn_wd_fils_rx(struct wpa_supplicant *wpa_s, struct wpabuf *wd)
395 {
396 struct wpas_pasn *pasn = &wpa_s->pasn;
397 struct ieee802_11_elems elems;
398 struct wpa_ie_data rsne_data;
399 u8 rmsk[ERP_MAX_KEY_LEN];
400 size_t rmsk_len;
401 u8 anonce[FILS_NONCE_LEN];
402 const u8 *data;
403 size_t buf_len;
404 struct wpabuf *fils_wd = NULL;
405 u16 alg, seq, status;
406 int ret;
407
408 if (!wd)
409 return -1;
410
411 data = wpabuf_head(wd);
412 buf_len = wpabuf_len(wd);
413
414 wpa_hexdump(MSG_DEBUG, "PASN: FILS: Authentication frame len=%zu",
415 data, buf_len);
416
417 /* first handle the header */
418 if (buf_len < 6) {
419 wpa_printf(MSG_DEBUG, "PASN: FILS: Buffer too short");
420 return -1;
421 }
422
423 alg = WPA_GET_LE16(data);
424 seq = WPA_GET_LE16(data + 2);
425 status = WPA_GET_LE16(data + 4);
426
427 wpa_printf(MSG_DEBUG, "PASN: FILS: commit: alg=%u, seq=%u, status=%u",
428 alg, seq, status);
429
430 if (alg != WLAN_AUTH_FILS_SK || seq != 2 ||
431 status != WLAN_STATUS_SUCCESS) {
432 wpa_printf(MSG_DEBUG,
433 "PASN: FILS: Dropping peer authentication");
434 return -1;
435 }
436
437 data += 6;
438 buf_len -= 6;
439
440 if (ieee802_11_parse_elems(data, buf_len, &elems, 1) == ParseFailed) {
441 wpa_printf(MSG_DEBUG, "PASN: FILS: Could not parse elements");
442 return -1;
443 }
444
445 if (!elems.rsn_ie || !elems.fils_nonce || !elems.fils_nonce ||
446 !elems.wrapped_data) {
447 wpa_printf(MSG_DEBUG, "PASN: FILS: Missing IEs");
448 return -1;
449 }
450
451 ret = wpa_parse_wpa_ie(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
452 &rsne_data);
453 if (ret) {
454 wpa_printf(MSG_DEBUG, "PASN: FILS: Failed parsing RNSE");
455 return -1;
456 }
457
458 ret = wpa_pasn_validate_rsne(&rsne_data);
459 if (ret) {
460 wpa_printf(MSG_DEBUG, "PASN: FILS: Failed validating RSNE");
461 return -1;
462 }
463
464 if (rsne_data.num_pmkid) {
465 wpa_printf(MSG_DEBUG,
466 "PASN: FILS: Not expecting PMKID in RSNE");
467 return -1;
468 }
469
470 wpa_hexdump(MSG_DEBUG, "PASN: FILS: ANonce", elems.fils_nonce,
471 FILS_NONCE_LEN);
472 os_memcpy(anonce, elems.fils_nonce, FILS_NONCE_LEN);
473
474 wpa_hexdump(MSG_DEBUG, "PASN: FILS: FILS Session", elems.fils_session,
475 FILS_SESSION_LEN);
476
477 if (os_memcmp(pasn->fils.session, elems.fils_session,
478 FILS_SESSION_LEN)) {
479 wpa_printf(MSG_DEBUG, "PASN: FILS: Session mismatch");
480 return -1;
481 }
482
483 fils_wd = ieee802_11_defrag(&elems, WLAN_EID_EXTENSION,
484 WLAN_EID_EXT_WRAPPED_DATA);
485
486 if (!fils_wd) {
487 wpa_printf(MSG_DEBUG,
488 "PASN: FILS: Failed getting wrapped data");
489 return -1;
490 }
491
492 eapol_sm_process_erp_finish(wpa_s->eapol, wpabuf_head(fils_wd),
493 wpabuf_len(fils_wd));
494
495 wpabuf_free(fils_wd);
496 fils_wd = NULL;
497
498 if (eapol_sm_failed(wpa_s->eapol)) {
499 wpa_printf(MSG_DEBUG, "PASN: FILS: ERP finish failed");
500 return -1;
501 }
502
503 rmsk_len = ERP_MAX_KEY_LEN;
504 ret = eapol_sm_get_key(wpa_s->eapol, rmsk, rmsk_len);
505
506 if (ret == PMK_LEN) {
507 rmsk_len = PMK_LEN;
508 ret = eapol_sm_get_key(wpa_s->eapol, rmsk, rmsk_len);
509 }
510
511 if (ret) {
512 wpa_printf(MSG_DEBUG, "PASN: FILS: Failed getting RMSK");
513 return -1;
514 }
515
516 ret = fils_rmsk_to_pmk(pasn->akmp, rmsk, rmsk_len,
517 pasn->fils.nonce, anonce, NULL, 0,
518 pasn->pmk, &pasn->pmk_len);
519
520 forced_memzero(rmsk, sizeof(rmsk));
521
522 if (ret) {
523 wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to derive PMK");
524 return -1;
525 }
526
527 wpa_hexdump(MSG_DEBUG, "PASN: FILS: PMKID", pasn->fils.erp_pmkid,
528 PMKID_LEN);
529
530 wpa_printf(MSG_DEBUG, "PASN: FILS: ERP processing succeeded");
531
532 wpa_pasn_pmksa_cache_add(wpa_s->wpa, pasn->pmk,
533 pasn->pmk_len, pasn->fils.erp_pmkid,
534 pasn->bssid, pasn->akmp);
535
536 pasn->fils.completed = true;
537 return 0;
538 }
539
540 #endif /* CONFIG_FILS */
541
542
wpas_pasn_get_wrapped_data(struct wpa_supplicant * wpa_s)543 static struct wpabuf * wpas_pasn_get_wrapped_data(struct wpa_supplicant *wpa_s)
544 {
545 struct wpas_pasn *pasn = &wpa_s->pasn;
546
547 if (pasn->using_pmksa)
548 return NULL;
549
550 switch (pasn->akmp) {
551 case WPA_KEY_MGMT_PASN:
552 /* no wrapped data */
553 return NULL;
554 case WPA_KEY_MGMT_SAE:
555 #ifdef CONFIG_SAE
556 if (pasn->trans_seq == 0)
557 return wpas_pasn_wd_sae_commit(wpa_s);
558 if (pasn->trans_seq == 2)
559 return wpas_pasn_wd_sae_confirm(wpa_s);
560 #endif /* CONFIG_SAE */
561 wpa_printf(MSG_ERROR,
562 "PASN: SAE: Cannot derive wrapped data");
563 return NULL;
564 case WPA_KEY_MGMT_FILS_SHA256:
565 case WPA_KEY_MGMT_FILS_SHA384:
566 #ifdef CONFIG_FILS
567 return wpas_pasn_wd_fils_auth(wpa_s);
568 #endif /* CONFIG_FILS */
569 case WPA_KEY_MGMT_FT_PSK:
570 case WPA_KEY_MGMT_FT_IEEE8021X:
571 case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
572 /*
573 * Wrapped data with these AKMs is optional and is only needed
574 * for further validation of FT security parameters. For now do
575 * not use them.
576 */
577 return NULL;
578 default:
579 wpa_printf(MSG_ERROR,
580 "PASN: TODO: Wrapped data for akmp=0x%x",
581 pasn->akmp);
582 return NULL;
583 }
584 }
585
586
wpas_pasn_get_wrapped_data_format(struct wpas_pasn * pasn)587 static u8 wpas_pasn_get_wrapped_data_format(struct wpas_pasn *pasn)
588 {
589 if (pasn->using_pmksa)
590 return WPA_PASN_WRAPPED_DATA_NO;
591
592 /* Note: Valid AKMP is expected to already be validated */
593 switch (pasn->akmp) {
594 case WPA_KEY_MGMT_SAE:
595 return WPA_PASN_WRAPPED_DATA_SAE;
596 case WPA_KEY_MGMT_FILS_SHA256:
597 case WPA_KEY_MGMT_FILS_SHA384:
598 return WPA_PASN_WRAPPED_DATA_FILS_SK;
599 case WPA_KEY_MGMT_FT_PSK:
600 case WPA_KEY_MGMT_FT_IEEE8021X:
601 case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
602 /*
603 * Wrapped data with these AKMs is optional and is only needed
604 * for further validation of FT security parameters. For now do
605 * not use them.
606 */
607 return WPA_PASN_WRAPPED_DATA_NO;
608 case WPA_KEY_MGMT_PASN:
609 default:
610 return WPA_PASN_WRAPPED_DATA_NO;
611 }
612 }
613
614
wpas_pasn_build_auth_1(struct wpa_supplicant * wpa_s)615 static struct wpabuf * wpas_pasn_build_auth_1(struct wpa_supplicant *wpa_s)
616 {
617 struct wpas_pasn *pasn = &wpa_s->pasn;
618 struct wpabuf *buf, *pubkey = NULL, *wrapped_data_buf = NULL;
619 const u8 *pmkid;
620 u8 wrapped_data;
621 int ret;
622 u16 capab;
623
624 wpa_printf(MSG_DEBUG, "PASN: Building frame 1");
625
626 if (pasn->trans_seq)
627 return NULL;
628
629 buf = wpabuf_alloc(1500);
630 if (!buf)
631 goto fail;
632
633 /* Get public key */
634 pubkey = crypto_ecdh_get_pubkey(pasn->ecdh, 0);
635 pubkey = wpabuf_zeropad(pubkey, crypto_ecdh_prime_len(pasn->ecdh));
636 if (!pubkey) {
637 wpa_printf(MSG_DEBUG, "PASN: Failed to get pubkey");
638 goto fail;
639 }
640
641 wrapped_data = wpas_pasn_get_wrapped_data_format(pasn);
642
643 wpa_pasn_build_auth_header(buf, pasn->bssid,
644 wpa_s->own_addr, pasn->bssid,
645 pasn->trans_seq + 1, WLAN_STATUS_SUCCESS);
646
647 pmkid = NULL;
648 if (wpa_key_mgmt_ft(pasn->akmp)) {
649 ret = wpa_pasn_ft_derive_pmk_r1(wpa_s->wpa, pasn->akmp,
650 pasn->bssid,
651 pasn->pmk_r1,
652 &pasn->pmk_r1_len,
653 pasn->pmk_r1_name);
654 if (ret) {
655 wpa_printf(MSG_DEBUG,
656 "PASN: FT: Failed to derive keys");
657 goto fail;
658 }
659
660 pmkid = pasn->pmk_r1_name;
661 } else if (wrapped_data != WPA_PASN_WRAPPED_DATA_NO) {
662 struct rsn_pmksa_cache_entry *pmksa;
663
664 pmksa = wpa_sm_pmksa_cache_get(wpa_s->wpa, pasn->bssid,
665 NULL, NULL, pasn->akmp);
666 if (pmksa)
667 pmkid = pmksa->pmkid;
668
669 /*
670 * Note: Even when PMKSA is available, also add wrapped data as
671 * it is possible that the PMKID is no longer valid at the AP.
672 */
673 wrapped_data_buf = wpas_pasn_get_wrapped_data(wpa_s);
674 }
675
676 if (wpa_pasn_add_rsne(buf, pmkid, pasn->akmp, pasn->cipher) < 0)
677 goto fail;
678
679 if (!wrapped_data_buf)
680 wrapped_data = WPA_PASN_WRAPPED_DATA_NO;
681
682 wpa_pasn_add_parameter_ie(buf, pasn->group, wrapped_data,
683 pubkey, NULL, -1);
684
685 if (wpa_pasn_add_wrapped_data(buf, wrapped_data_buf) < 0)
686 goto fail;
687
688 /* Add own RNSXE */
689 /* TODO: How to handle protected TWT and SAE H2E? */
690 capab = 0;
691 if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF)
692 capab |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF);
693 if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_RTT)
694 capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT);
695 if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG)
696 capab |= BIT(WLAN_RSNX_CAPAB_PROT_RANGE_NEG);
697 wpa_pasn_add_rsnxe(buf, capab);
698
699 ret = pasn_auth_frame_hash(pasn->akmp, pasn->cipher,
700 wpabuf_head_u8(buf) + IEEE80211_HDRLEN,
701 wpabuf_len(buf) - IEEE80211_HDRLEN,
702 pasn->hash);
703 if (ret) {
704 wpa_printf(MSG_DEBUG, "PASN: Failed to compute hash");
705 goto fail;
706 }
707
708 pasn->trans_seq++;
709
710 wpabuf_free(wrapped_data_buf);
711 wpabuf_free(pubkey);
712
713 wpa_printf(MSG_DEBUG, "PASN: Frame 1: Success");
714 return buf;
715 fail:
716 pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
717 wpabuf_free(wrapped_data_buf);
718 wpabuf_free(pubkey);
719 wpabuf_free(buf);
720 return NULL;
721 }
722
723
wpas_pasn_build_auth_3(struct wpa_supplicant * wpa_s)724 static struct wpabuf * wpas_pasn_build_auth_3(struct wpa_supplicant *wpa_s)
725 {
726 struct wpas_pasn *pasn = &wpa_s->pasn;
727 struct wpabuf *buf, *wrapped_data_buf = NULL;
728 u8 mic[WPA_PASN_MAX_MIC_LEN];
729 u8 mic_len, data_len;
730 const u8 *data;
731 u8 *ptr;
732 u8 wrapped_data;
733 int ret;
734
735 wpa_printf(MSG_DEBUG, "PASN: Building frame 3");
736
737 if (pasn->trans_seq != 2)
738 return NULL;
739
740 buf = wpabuf_alloc(1500);
741 if (!buf)
742 goto fail;
743
744 wrapped_data = wpas_pasn_get_wrapped_data_format(pasn);
745
746 wpa_pasn_build_auth_header(buf, pasn->bssid,
747 wpa_s->own_addr, pasn->bssid,
748 pasn->trans_seq + 1, WLAN_STATUS_SUCCESS);
749
750 wrapped_data_buf = wpas_pasn_get_wrapped_data(wpa_s);
751
752 if (!wrapped_data_buf)
753 wrapped_data = WPA_PASN_WRAPPED_DATA_NO;
754
755 wpa_pasn_add_parameter_ie(buf, pasn->group, wrapped_data,
756 NULL, NULL, -1);
757
758 if (wpa_pasn_add_wrapped_data(buf, wrapped_data_buf) < 0)
759 goto fail;
760 wpabuf_free(wrapped_data_buf);
761 wrapped_data_buf = NULL;
762
763 /* Add the MIC */
764 mic_len = pasn_mic_len(pasn->akmp, pasn->cipher);
765 wpabuf_put_u8(buf, WLAN_EID_MIC);
766 wpabuf_put_u8(buf, mic_len);
767 ptr = wpabuf_put(buf, mic_len);
768
769 os_memset(ptr, 0, mic_len);
770
771 data = wpabuf_head_u8(buf) + IEEE80211_HDRLEN;
772 data_len = wpabuf_len(buf) - IEEE80211_HDRLEN;
773
774 ret = pasn_mic(pasn->ptk.kck, pasn->akmp, pasn->cipher,
775 wpa_s->own_addr, pasn->bssid,
776 pasn->hash, mic_len * 2, data, data_len, mic);
777 if (ret) {
778 wpa_printf(MSG_DEBUG, "PASN: frame 3: Failed MIC calculation");
779 goto fail;
780 }
781
782 os_memcpy(ptr, mic, mic_len);
783
784 pasn->trans_seq++;
785
786 wpa_printf(MSG_DEBUG, "PASN: frame 3: Success");
787 return buf;
788 fail:
789 pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
790 wpabuf_free(wrapped_data_buf);
791 wpabuf_free(buf);
792 return NULL;
793 }
794
795
wpas_pasn_reset(struct wpa_supplicant * wpa_s)796 static void wpas_pasn_reset(struct wpa_supplicant *wpa_s)
797 {
798 struct wpas_pasn *pasn = &wpa_s->pasn;
799
800 wpa_printf(MSG_DEBUG, "PASN: Reset");
801
802 crypto_ecdh_deinit(pasn->ecdh);
803 pasn->ecdh = NULL;
804
805 wpas_pasn_cancel_auth_work(wpa_s);
806 wpa_s->pasn_auth_work = NULL;
807
808 eloop_cancel_timeout(wpas_pasn_auth_work_timeout, wpa_s, NULL);
809
810 pasn->akmp = 0;
811 pasn->cipher = 0;
812 pasn->group = 0;
813 pasn->trans_seq = 0;
814 pasn->pmk_len = 0;
815 pasn->using_pmksa = false;
816
817 forced_memzero(pasn->pmk, sizeof(pasn->pmk));
818 forced_memzero(&pasn->ptk, sizeof(pasn->ptk));
819 forced_memzero(&pasn->hash, sizeof(pasn->hash));
820
821 wpabuf_free(pasn->beacon_rsne_rsnxe);
822 pasn->beacon_rsne_rsnxe = NULL;
823
824 #ifdef CONFIG_SAE
825 sae_clear_data(&pasn->sae);
826 #endif /* CONFIG_SAE */
827
828 #ifdef CONFIG_FILS
829 os_memset(&pasn->fils, 0, sizeof(pasn->fils));
830 #endif /* CONFIG_FILS*/
831
832 #ifdef CONFIG_IEEE80211R
833 forced_memzero(pasn->pmk_r1, sizeof(pasn->pmk_r1));
834 pasn->pmk_r1_len = 0;
835 os_memset(pasn->pmk_r1_name, 0, sizeof(pasn->pmk_r1_name));
836 #endif /* CONFIG_IEEE80211R */
837 pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
838 }
839
840
wpas_pasn_set_pmk(struct wpa_supplicant * wpa_s,struct wpa_ie_data * rsn_data,struct wpa_pasn_params_data * pasn_data,struct wpabuf * wrapped_data)841 static int wpas_pasn_set_pmk(struct wpa_supplicant *wpa_s,
842 struct wpa_ie_data *rsn_data,
843 struct wpa_pasn_params_data *pasn_data,
844 struct wpabuf *wrapped_data)
845 {
846 static const u8 pasn_default_pmk[] = {'P', 'M', 'K', 'z'};
847 struct wpas_pasn *pasn = &wpa_s->pasn;
848
849 os_memset(pasn->pmk, 0, sizeof(pasn->pmk));
850 pasn->pmk_len = 0;
851
852 if (pasn->akmp == WPA_KEY_MGMT_PASN) {
853 wpa_printf(MSG_DEBUG, "PASN: Using default PMK");
854
855 pasn->pmk_len = WPA_PASN_PMK_LEN;
856 os_memcpy(pasn->pmk, pasn_default_pmk,
857 sizeof(pasn_default_pmk));
858 return 0;
859 }
860
861 if (wpa_key_mgmt_ft(pasn->akmp)) {
862 #ifdef CONFIG_IEEE80211R
863 wpa_printf(MSG_DEBUG, "PASN: FT: Using PMK-R1");
864 pasn->pmk_len = pasn->pmk_r1_len;
865 os_memcpy(pasn->pmk, pasn->pmk_r1, pasn->pmk_r1_len);
866 pasn->using_pmksa = true;
867 return 0;
868 #else /* CONFIG_IEEE80211R */
869 wpa_printf(MSG_DEBUG, "PASN: FT: Not supported");
870 return -1;
871 #endif /* CONFIG_IEEE80211R */
872 }
873
874 if (rsn_data->num_pmkid) {
875 struct rsn_pmksa_cache_entry *pmksa;
876
877 pmksa = wpa_sm_pmksa_cache_get(wpa_s->wpa, pasn->bssid,
878 rsn_data->pmkid, NULL,
879 pasn->akmp);
880 if (pmksa) {
881 wpa_printf(MSG_DEBUG, "PASN: Using PMKSA");
882
883 pasn->pmk_len = pmksa->pmk_len;
884 os_memcpy(pasn->pmk, pmksa->pmk, pmksa->pmk_len);
885 pasn->using_pmksa = true;
886
887 return 0;
888 }
889 }
890
891 #ifdef CONFIG_SAE
892 if (pasn->akmp == WPA_KEY_MGMT_SAE) {
893 int ret;
894
895 ret = wpas_pasn_wd_sae_rx(wpa_s, wrapped_data);
896 if (ret) {
897 wpa_printf(MSG_DEBUG,
898 "PASN: Failed processing SAE wrapped data");
899 pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
900 return -1;
901 }
902
903 wpa_printf(MSG_DEBUG, "PASN: Success deriving PMK with SAE");
904 pasn->pmk_len = PMK_LEN;
905 os_memcpy(pasn->pmk, pasn->sae.pmk, PMK_LEN);
906
907 wpa_pasn_pmksa_cache_add(wpa_s->wpa, pasn->pmk,
908 pasn->pmk_len, pasn->sae.pmkid,
909 pasn->bssid, pasn->akmp);
910 return 0;
911 }
912 #endif /* CONFIG_SAE */
913
914 #ifdef CONFIG_FILS
915 if (pasn->akmp == WPA_KEY_MGMT_FILS_SHA256 ||
916 pasn->akmp == WPA_KEY_MGMT_FILS_SHA384) {
917 int ret;
918
919 ret = wpas_pasn_wd_fils_rx(wpa_s, wrapped_data);
920 if (ret) {
921 wpa_printf(MSG_DEBUG,
922 "PASN: Failed processing FILS wrapped data");
923 pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
924 return -1;
925 }
926
927 return 0;
928 }
929 #endif /* CONFIG_FILS */
930
931 /* TODO: Derive PMK based on wrapped data */
932 wpa_printf(MSG_DEBUG, "PASN: Missing implementation to derive PMK");
933 pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
934 return -1;
935 }
936
937
wpas_pasn_start(struct wpa_supplicant * wpa_s,const u8 * bssid,int akmp,int cipher,u16 group,int freq,const u8 * beacon_rsne,u8 beacon_rsne_len,const u8 * beacon_rsnxe,u8 beacon_rsnxe_len,int network_id)938 static int wpas_pasn_start(struct wpa_supplicant *wpa_s, const u8 *bssid,
939 int akmp, int cipher, u16 group, int freq,
940 const u8 *beacon_rsne, u8 beacon_rsne_len,
941 const u8 *beacon_rsnxe, u8 beacon_rsnxe_len,
942 int network_id)
943 {
944 struct wpas_pasn *pasn = &wpa_s->pasn;
945 struct wpa_ssid *ssid = NULL;
946 struct wpabuf *frame;
947 int ret;
948
949 /* TODO: Currently support only ECC groups */
950 if (!dragonfly_suitable_group(group, 1)) {
951 wpa_printf(MSG_DEBUG,
952 "PASN: Reject unsuitable group %u", group);
953 return -1;
954 }
955
956 ssid = wpa_config_get_network(wpa_s->conf, network_id);
957
958 switch (akmp) {
959 case WPA_KEY_MGMT_PASN:
960 break;
961 #ifdef CONFIG_SAE
962 case WPA_KEY_MGMT_SAE:
963 if (!ssid) {
964 wpa_printf(MSG_DEBUG,
965 "PASN: No network profile found for SAE");
966 return -1;
967 }
968 pasn->sae.state = SAE_NOTHING;
969 pasn->sae.send_confirm = 0;
970 pasn->ssid = ssid;
971 break;
972 #endif /* CONFIG_SAE */
973 #ifdef CONFIG_FILS
974 case WPA_KEY_MGMT_FILS_SHA256:
975 case WPA_KEY_MGMT_FILS_SHA384:
976 pasn->ssid = ssid;
977 break;
978 #endif /* CONFIG_FILS */
979 #ifdef CONFIG_IEEE80211R
980 case WPA_KEY_MGMT_FT_PSK:
981 case WPA_KEY_MGMT_FT_IEEE8021X:
982 case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
983 break;
984 #endif /* CONFIG_IEEE80211R */
985 default:
986 wpa_printf(MSG_ERROR, "PASN: Unsupported AKMP=0x%x", akmp);
987 return -1;
988 }
989
990 pasn->ecdh = crypto_ecdh_init(group);
991 if (!pasn->ecdh) {
992 wpa_printf(MSG_DEBUG, "PASN: Failed to init ECDH");
993 goto fail;
994 }
995
996 pasn->beacon_rsne_rsnxe = wpabuf_alloc(beacon_rsne_len +
997 beacon_rsnxe_len);
998 if (!pasn->beacon_rsne_rsnxe) {
999 wpa_printf(MSG_DEBUG, "PASN: Failed storing beacon RSNE/RSNXE");
1000 goto fail;
1001 }
1002
1003 wpabuf_put_data(pasn->beacon_rsne_rsnxe, beacon_rsne, beacon_rsne_len);
1004 if (beacon_rsnxe && beacon_rsnxe_len)
1005 wpabuf_put_data(pasn->beacon_rsne_rsnxe, beacon_rsnxe,
1006 beacon_rsnxe_len);
1007
1008 pasn->akmp = akmp;
1009 pasn->cipher = cipher;
1010 pasn->group = group;
1011 pasn->freq = freq;
1012 os_memcpy(pasn->bssid, bssid, ETH_ALEN);
1013
1014 wpa_printf(MSG_DEBUG,
1015 "PASN: Init: " MACSTR " akmp=0x%x, cipher=0x%x, group=%u",
1016 MAC2STR(pasn->bssid), pasn->akmp, pasn->cipher,
1017 pasn->group);
1018
1019 frame = wpas_pasn_build_auth_1(wpa_s);
1020 if (!frame) {
1021 wpa_printf(MSG_DEBUG, "PASN: Failed building 1st auth frame");
1022 goto fail;
1023 }
1024
1025 ret = wpa_drv_send_mlme(wpa_s, wpabuf_head(frame), wpabuf_len(frame), 0,
1026 pasn->freq, 1000);
1027
1028 wpabuf_free(frame);
1029 if (ret) {
1030 wpa_printf(MSG_DEBUG, "PASN: Failed sending 1st auth frame");
1031 goto fail;
1032 }
1033
1034 eloop_register_timeout(2, 0, wpas_pasn_auth_work_timeout, wpa_s, NULL);
1035 return 0;
1036
1037 fail:
1038 return -1;
1039 }
1040
1041
wpas_pasn_allowed(struct wpa_supplicant * wpa_s,const u8 * bssid,int akmp,int cipher)1042 static struct wpa_bss * wpas_pasn_allowed(struct wpa_supplicant *wpa_s,
1043 const u8 *bssid, int akmp, int cipher)
1044 {
1045 struct wpa_bss *bss;
1046 const u8 *rsne;
1047 struct wpa_ie_data rsne_data;
1048 int ret;
1049
1050 if (os_memcmp(wpa_s->bssid, bssid, ETH_ALEN) == 0) {
1051 wpa_printf(MSG_DEBUG,
1052 "PASN: Not doing authentication with current BSS");
1053 return NULL;
1054 }
1055
1056 bss = wpa_bss_get_bssid(wpa_s, bssid);
1057 if (!bss) {
1058 wpa_printf(MSG_DEBUG, "PASN: BSS not found");
1059 return NULL;
1060 }
1061
1062 rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1063 if (!rsne) {
1064 wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
1065 return NULL;
1066 }
1067
1068 ret = wpa_parse_wpa_ie(rsne, *(rsne + 1) + 2, &rsne_data);
1069 if (ret) {
1070 wpa_printf(MSG_DEBUG, "PASN: Failed parsing RSNE data");
1071 return NULL;
1072 }
1073
1074 if (!(rsne_data.key_mgmt & akmp) ||
1075 !(rsne_data.pairwise_cipher & cipher)) {
1076 wpa_printf(MSG_DEBUG,
1077 "PASN: AP does not support requested AKMP or cipher");
1078 return NULL;
1079 }
1080
1081 return bss;
1082 }
1083
1084
wpas_pasn_auth_start_cb(struct wpa_radio_work * work,int deinit)1085 static void wpas_pasn_auth_start_cb(struct wpa_radio_work *work, int deinit)
1086 {
1087 struct wpa_supplicant *wpa_s = work->wpa_s;
1088 struct wpa_pasn_auth_work *awork = work->ctx;
1089 struct wpa_bss *bss;
1090 const u8 *rsne, *rsnxe;
1091 int ret;
1092
1093 wpa_printf(MSG_DEBUG, "PASN: auth_start_cb: deinit=%d", deinit);
1094
1095 if (deinit) {
1096 if (work->started) {
1097 eloop_cancel_timeout(wpas_pasn_auth_work_timeout,
1098 wpa_s, NULL);
1099 wpa_s->pasn_auth_work = NULL;
1100 }
1101 os_free(awork);
1102 return;
1103 }
1104
1105 /*
1106 * It is possible that by the time the callback is called, the PASN
1107 * authentication is not allowed, e.g., a connection with the AP was
1108 * established.
1109 */
1110 bss = wpas_pasn_allowed(wpa_s, awork->bssid, awork->akmp,
1111 awork->cipher);
1112 if (!bss) {
1113 wpa_printf(MSG_DEBUG, "PASN: auth_start_cb: Not allowed");
1114 goto fail;
1115 }
1116
1117 rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1118 if (!rsne) {
1119 wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
1120 goto fail;
1121 }
1122
1123 rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
1124
1125 ret = wpas_pasn_start(wpa_s, awork->bssid, awork->akmp, awork->cipher,
1126 awork->group, bss->freq, rsne, *(rsne + 1) + 2,
1127 rsnxe, rsnxe ? *(rsnxe + 1) + 2 : 0,
1128 awork->network_id);
1129 if (ret) {
1130 wpa_printf(MSG_DEBUG,
1131 "PASN: Failed to start PASN authentication");
1132 goto fail;
1133 }
1134
1135 wpa_s->pasn_auth_work = work;
1136 return;
1137 fail:
1138 os_free(awork);
1139 work->ctx = NULL;
1140 radio_work_done(work);
1141 }
1142
1143
wpas_pasn_auth_start(struct wpa_supplicant * wpa_s,const u8 * bssid,int akmp,int cipher,u16 group,int network_id)1144 int wpas_pasn_auth_start(struct wpa_supplicant *wpa_s, const u8 *bssid,
1145 int akmp, int cipher, u16 group, int network_id)
1146 {
1147 struct wpa_pasn_auth_work *awork;
1148 struct wpa_bss *bss;
1149
1150 wpa_printf(MSG_DEBUG, "PASN: Start: " MACSTR " akmp=0x%x, cipher=0x%x",
1151 MAC2STR(bssid), akmp, cipher);
1152
1153 /*
1154 * TODO: Consider modifying the offchannel logic to handle additional
1155 * Management frames other then Action frames. For now allow PASN only
1156 * with drivers that support off-channel TX.
1157 */
1158 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX)) {
1159 wpa_printf(MSG_DEBUG,
1160 "PASN: Driver does not support offchannel TX");
1161 return -1;
1162 }
1163
1164 if (radio_work_pending(wpa_s, "pasn-start-auth")) {
1165 wpa_printf(MSG_DEBUG,
1166 "PASN: send_auth: Work is already pending");
1167 return -1;
1168 }
1169
1170 if (wpa_s->pasn_auth_work) {
1171 wpa_printf(MSG_DEBUG, "PASN: send_auth: Already in progress");
1172 return -1;
1173 }
1174
1175 bss = wpas_pasn_allowed(wpa_s, bssid, akmp, cipher);
1176 if (!bss)
1177 return -1;
1178
1179 wpas_pasn_reset(wpa_s);
1180
1181 awork = os_zalloc(sizeof(*awork));
1182 if (!awork)
1183 return -1;
1184
1185 os_memcpy(awork->bssid, bssid, ETH_ALEN);
1186 awork->akmp = akmp;
1187 awork->cipher = cipher;
1188 awork->group = group;
1189 awork->network_id = network_id;
1190
1191 if (radio_add_work(wpa_s, bss->freq, "pasn-start-auth", 1,
1192 wpas_pasn_auth_start_cb, awork) < 0) {
1193 os_free(awork);
1194 return -1;
1195 }
1196
1197 wpa_printf(MSG_DEBUG, "PASN: Auth work successfully added");
1198 return 0;
1199 }
1200
1201
wpas_pasn_auth_stop(struct wpa_supplicant * wpa_s)1202 void wpas_pasn_auth_stop(struct wpa_supplicant *wpa_s)
1203 {
1204 struct wpas_pasn *pasn = &wpa_s->pasn;
1205
1206 if (!wpa_s->pasn.ecdh)
1207 return;
1208
1209 wpa_printf(MSG_DEBUG, "PASN: Stopping authentication");
1210
1211 wpas_pasn_auth_status(wpa_s, pasn->bssid, pasn->akmp, pasn->cipher,
1212 pasn->status);
1213
1214 wpas_pasn_reset(wpa_s);
1215 }
1216
1217
wpas_pasn_auth_rx(struct wpa_supplicant * wpa_s,const struct ieee80211_mgmt * mgmt,size_t len)1218 int wpas_pasn_auth_rx(struct wpa_supplicant *wpa_s,
1219 const struct ieee80211_mgmt *mgmt, size_t len)
1220 {
1221 struct wpas_pasn *pasn = &wpa_s->pasn;
1222 struct ieee802_11_elems elems;
1223 struct wpa_ie_data rsn_data;
1224 struct wpa_pasn_params_data pasn_params;
1225 struct wpabuf *wrapped_data = NULL, *secret = NULL, *frame = NULL;
1226 u8 mic[WPA_PASN_MAX_MIC_LEN], out_mic[WPA_PASN_MAX_MIC_LEN];
1227 u8 mic_len;
1228 u16 status;
1229 int ret;
1230 u16 fc = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
1231 (WLAN_FC_STYPE_AUTH << 4));
1232
1233 if (!wpa_s->pasn_auth_work || !mgmt ||
1234 len < offsetof(struct ieee80211_mgmt, u.auth.variable))
1235 return -2;
1236
1237 /* Not an Authentication frame; do nothing */
1238 if ((mgmt->frame_control & fc) != fc)
1239 return -2;
1240
1241 /* Not our frame; do nothing */
1242 if (os_memcmp(mgmt->da, wpa_s->own_addr, ETH_ALEN) != 0 ||
1243 os_memcmp(mgmt->sa, pasn->bssid, ETH_ALEN) != 0 ||
1244 os_memcmp(mgmt->bssid, pasn->bssid, ETH_ALEN) != 0)
1245 return -2;
1246
1247 /* Not PASN; do nothing */
1248 if (mgmt->u.auth.auth_alg != host_to_le16(WLAN_AUTH_PASN))
1249 return -2;
1250
1251 if (mgmt->u.auth.auth_transaction !=
1252 host_to_le16(pasn->trans_seq + 1)) {
1253 wpa_printf(MSG_DEBUG,
1254 "PASN: RX: Invalid transaction sequence: (%u != %u)",
1255 le_to_host16(mgmt->u.auth.auth_transaction),
1256 pasn->trans_seq + 1);
1257 return -1;
1258 }
1259
1260 status = le_to_host16(mgmt->u.auth.status_code);
1261
1262 if (status != WLAN_STATUS_SUCCESS &&
1263 status != WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) {
1264 wpa_printf(MSG_DEBUG,
1265 "PASN: Authentication rejected - status=%u", status);
1266 pasn->status = status;
1267 wpas_pasn_auth_stop(wpa_s);
1268 return -1;
1269 }
1270
1271 if (ieee802_11_parse_elems(mgmt->u.auth.variable,
1272 len - offsetof(struct ieee80211_mgmt,
1273 u.auth.variable),
1274 &elems, 0) == ParseFailed) {
1275 wpa_printf(MSG_DEBUG,
1276 "PASN: Failed parsing Authentication frame");
1277 goto fail;
1278 }
1279
1280 /* Check that the MIC IE exists. Save it and zero out the memory */
1281 mic_len = pasn_mic_len(pasn->akmp, pasn->cipher);
1282 if (status == WLAN_STATUS_SUCCESS) {
1283 if (!elems.mic || elems.mic_len != mic_len) {
1284 wpa_printf(MSG_DEBUG,
1285 "PASN: Invalid MIC. Expecting len=%u",
1286 mic_len);
1287 goto fail;
1288 } else {
1289 os_memcpy(mic, elems.mic, mic_len);
1290 /* TODO: Clean this up.. Should not be modifying the
1291 * received message buffer. */
1292 os_memset((u8 *) elems.mic, 0, mic_len);
1293 }
1294 }
1295
1296 if (!elems.pasn_params || !elems.pasn_params_len) {
1297 wpa_printf(MSG_DEBUG,
1298 "PASN: Missing PASN Parameters IE");
1299 goto fail;
1300 }
1301
1302 ret = wpa_pasn_parse_parameter_ie(elems.pasn_params - 3,
1303 elems.pasn_params_len + 3,
1304 true, &pasn_params);
1305 if (ret) {
1306 wpa_printf(MSG_DEBUG,
1307 "PASN: Failed validation PASN of Parameters IE");
1308 goto fail;
1309 }
1310
1311 /* TODO: handle comeback flow */
1312 if (status == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) {
1313 wpa_printf(MSG_DEBUG,
1314 "PASN: Authentication temporarily rejected");
1315 goto fail;
1316 }
1317
1318 ret = wpa_parse_wpa_ie(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
1319 &rsn_data);
1320 if (ret) {
1321 wpa_printf(MSG_DEBUG, "PASN: Failed parsing RNSE");
1322 goto fail;
1323 }
1324
1325 ret = wpa_pasn_validate_rsne(&rsn_data);
1326 if (ret) {
1327 wpa_printf(MSG_DEBUG, "PASN: Failed validating RSNE");
1328 goto fail;
1329 }
1330
1331 if (pasn->akmp != rsn_data.key_mgmt ||
1332 pasn->cipher != rsn_data.pairwise_cipher) {
1333 wpa_printf(MSG_DEBUG, "PASN: Mismatch in AKMP/cipher");
1334 goto fail;
1335 }
1336
1337 if (pasn->group != pasn_params.group) {
1338 wpa_printf(MSG_DEBUG, "PASN: Mismatch in group");
1339 goto fail;
1340 }
1341
1342 if (!pasn_params.pubkey || !pasn_params.pubkey_len) {
1343 wpa_printf(MSG_DEBUG, "PASN: Invalid public key");
1344 goto fail;
1345 }
1346
1347 secret = crypto_ecdh_set_peerkey(pasn->ecdh, 0,
1348 pasn_params.pubkey,
1349 pasn_params.pubkey_len);
1350
1351 if (!secret) {
1352 wpa_printf(MSG_DEBUG, "PASN: Failed to derive shared secret");
1353 goto fail;
1354 }
1355
1356 if (pasn_params.wrapped_data_format != WPA_PASN_WRAPPED_DATA_NO) {
1357 wrapped_data = ieee802_11_defrag(&elems,
1358 WLAN_EID_EXTENSION,
1359 WLAN_EID_EXT_WRAPPED_DATA);
1360
1361 if (!wrapped_data) {
1362 wpa_printf(MSG_DEBUG, "PASN: Missing wrapped data");
1363 goto fail;
1364 }
1365 }
1366
1367 ret = wpas_pasn_set_pmk(wpa_s, &rsn_data, &pasn_params, wrapped_data);
1368 if (ret) {
1369 wpa_printf(MSG_DEBUG, "PASN: Failed to set PMK");
1370 goto fail;
1371 }
1372
1373 ret = pasn_pmk_to_ptk(pasn->pmk, pasn->pmk_len,
1374 wpa_s->own_addr, pasn->bssid,
1375 wpabuf_head(secret), wpabuf_len(secret),
1376 &pasn->ptk, pasn->akmp, pasn->cipher,
1377 WPA_KDK_MAX_LEN);
1378 if (ret) {
1379 wpa_printf(MSG_DEBUG, "PASN: Failed to derive PTK");
1380 goto fail;
1381 }
1382
1383 wpabuf_free(wrapped_data);
1384 wrapped_data = NULL;
1385 wpabuf_free(secret);
1386 secret = NULL;
1387
1388 /* Verify the MIC */
1389 ret = pasn_mic(pasn->ptk.kck, pasn->akmp, pasn->cipher,
1390 pasn->bssid, wpa_s->own_addr,
1391 wpabuf_head(pasn->beacon_rsne_rsnxe),
1392 wpabuf_len(pasn->beacon_rsne_rsnxe),
1393 (u8 *) &mgmt->u.auth,
1394 len - offsetof(struct ieee80211_mgmt, u.auth),
1395 out_mic);
1396
1397 wpa_hexdump_key(MSG_DEBUG, "PASN: Frame MIC", mic, mic_len);
1398 if (ret || os_memcmp(mic, out_mic, mic_len) != 0) {
1399 wpa_printf(MSG_DEBUG, "PASN: Failed MIC verification");
1400 goto fail;
1401 }
1402
1403 pasn->trans_seq++;
1404
1405 wpa_printf(MSG_DEBUG, "PASN: Success verifying Authentication frame");
1406
1407 frame = wpas_pasn_build_auth_3(wpa_s);
1408 if (!frame) {
1409 wpa_printf(MSG_DEBUG, "PASN: Failed building 3rd auth frame");
1410 goto fail;
1411 }
1412
1413 ret = wpa_drv_send_mlme(wpa_s, wpabuf_head(frame), wpabuf_len(frame), 0,
1414 pasn->freq, 100);
1415 wpabuf_free(frame);
1416 if (ret) {
1417 wpa_printf(MSG_DEBUG, "PASN: Failed sending 3st auth frame");
1418 goto fail;
1419 }
1420
1421 wpa_printf(MSG_DEBUG, "PASN: Success sending last frame. Store PTK");
1422
1423 ptksa_cache_add(wpa_s->ptksa, pasn->bssid, pasn->cipher,
1424 dot11RSNAConfigPMKLifetime, &pasn->ptk);
1425
1426 forced_memzero(&pasn->ptk, sizeof(pasn->ptk));
1427
1428 pasn->status = WLAN_STATUS_SUCCESS;
1429 return 0;
1430 fail:
1431 wpa_printf(MSG_DEBUG, "PASN: Failed RX processing - terminating");
1432 wpabuf_free(wrapped_data);
1433 wpabuf_free(secret);
1434
1435 /*
1436 * TODO: In case of an error the standard allows to silently drop
1437 * the frame and terminate the authentication exchange. However, better
1438 * reply to the AP with an error status.
1439 */
1440 pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1441 wpas_pasn_auth_stop(wpa_s);
1442 return -1;
1443 }
1444
1445
wpas_pasn_auth_tx_status(struct wpa_supplicant * wpa_s,const u8 * data,size_t data_len,u8 acked)1446 int wpas_pasn_auth_tx_status(struct wpa_supplicant *wpa_s,
1447 const u8 *data, size_t data_len, u8 acked)
1448
1449 {
1450 struct wpas_pasn *pasn = &wpa_s->pasn;
1451 const struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) data;
1452 u16 fc = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
1453 (WLAN_FC_STYPE_AUTH << 4));
1454
1455 wpa_printf(MSG_DEBUG, "PASN: auth_tx_status: acked=%u", acked);
1456
1457 if (!wpa_s->pasn_auth_work) {
1458 wpa_printf(MSG_DEBUG,
1459 "PASN: auth_tx_status: no work in progress");
1460 return -1;
1461 }
1462
1463 if (!mgmt ||
1464 data_len < offsetof(struct ieee80211_mgmt, u.auth.variable))
1465 return -1;
1466
1467 /* Not an authentication frame; do nothing */
1468 if ((mgmt->frame_control & fc) != fc)
1469 return -1;
1470
1471 /* Not our frame; do nothing */
1472 if (os_memcmp(mgmt->da, pasn->bssid, ETH_ALEN) ||
1473 os_memcmp(mgmt->sa, wpa_s->own_addr, ETH_ALEN) ||
1474 os_memcmp(mgmt->bssid, pasn->bssid, ETH_ALEN))
1475 return -1;
1476
1477 /* Not PASN; do nothing */
1478 if (mgmt->u.auth.auth_alg != host_to_le16(WLAN_AUTH_PASN))
1479 return -1;
1480
1481 if (mgmt->u.auth.auth_transaction != host_to_le16(pasn->trans_seq)) {
1482 wpa_printf(MSG_ERROR,
1483 "PASN: Invalid transaction sequence: (%u != %u)",
1484 pasn->trans_seq,
1485 le_to_host16(mgmt->u.auth.auth_transaction));
1486 return 0;
1487 }
1488
1489 wpa_printf(MSG_ERROR,
1490 "PASN: auth with trans_seq=%u, acked=%u", pasn->trans_seq,
1491 acked);
1492
1493 /*
1494 * Even if the frame was not acked, do not treat this is an error, and
1495 * try to complete the flow, relying on the PASN timeout callback to
1496 * clean up.
1497 */
1498 if (pasn->trans_seq == 3) {
1499 wpa_printf(MSG_DEBUG, "PASN: auth complete with: " MACSTR,
1500 MAC2STR(pasn->bssid));
1501 /*
1502 * Either frame was not ACKed or it was ACKed but the trans_seq
1503 * != 1, i.e., not expecting an RX frame, so we are done.
1504 */
1505 wpas_pasn_auth_stop(wpa_s);
1506 }
1507
1508 return 0;
1509 }
1510