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