1 /*
2 * PASN responder 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 "crypto/sha384.h"
19 #include "crypto/sha256.h"
20 #include "crypto/random.h"
21 #include "crypto/crypto.h"
22 #include "ap/hostapd.h"
23 #include "ap/comeback_token.h"
24 #include "ap/ieee802_1x.h"
25 #include "ap/pmksa_cache_auth.h"
26 #include "pasn_common.h"
27
28
pasn_set_responder_pmksa(struct pasn_data * pasn,struct rsn_pmksa_cache * pmksa)29 void pasn_set_responder_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_PASN
38 #ifdef CONFIG_SAE
39
pasn_wd_handle_sae_commit(struct pasn_data * pasn,const u8 * own_addr,const u8 * peer_addr,struct wpabuf * wd)40 static int pasn_wd_handle_sae_commit(struct pasn_data *pasn,
41 const u8 *own_addr, const u8 *peer_addr,
42 struct wpabuf *wd)
43 {
44 const u8 *data;
45 size_t buf_len;
46 u16 res, alg, seq, status;
47 int groups[] = { pasn->group, 0 };
48 int ret;
49
50 if (!wd)
51 return -1;
52
53 data = wpabuf_head_u8(wd);
54 buf_len = wpabuf_len(wd);
55
56 if (buf_len < 6) {
57 wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short. len=%zu",
58 buf_len);
59 return -1;
60 }
61
62 alg = WPA_GET_LE16(data);
63 seq = WPA_GET_LE16(data + 2);
64 status = WPA_GET_LE16(data + 4);
65
66 wpa_printf(MSG_DEBUG, "PASN: SAE commit: alg=%u, seq=%u, status=%u",
67 alg, seq, status);
68
69 if (alg != WLAN_AUTH_SAE || seq != 1 ||
70 status != WLAN_STATUS_SAE_HASH_TO_ELEMENT) {
71 wpa_printf(MSG_DEBUG, "PASN: Dropping peer SAE commit");
72 return -1;
73 }
74
75 sae_clear_data(&pasn->sae);
76 pasn->sae.state = SAE_NOTHING;
77
78 ret = sae_set_group(&pasn->sae, pasn->group);
79 if (ret) {
80 wpa_printf(MSG_DEBUG, "PASN: Failed to set SAE group");
81 return -1;
82 }
83
84 if (!pasn->password || !pasn->pt) {
85 wpa_printf(MSG_DEBUG, "PASN: No SAE PT found");
86 return -1;
87 }
88
89 ret = sae_prepare_commit_pt(&pasn->sae, pasn->pt, own_addr, peer_addr,
90 NULL, NULL);
91 if (ret) {
92 wpa_printf(MSG_DEBUG, "PASN: Failed to prepare SAE commit");
93 return -1;
94 }
95
96 res = sae_parse_commit(&pasn->sae, data + 6, buf_len - 6, NULL, 0,
97 groups, 0, NULL);
98 if (res != WLAN_STATUS_SUCCESS) {
99 wpa_printf(MSG_DEBUG, "PASN: Failed parsing SAE commit");
100 return -1;
101 }
102
103 /* Process the commit message and derive the PMK */
104 ret = sae_process_commit(&pasn->sae);
105 if (ret) {
106 wpa_printf(MSG_DEBUG, "SAE: Failed to process peer commit");
107 return -1;
108 }
109
110 pasn->sae.state = SAE_COMMITTED;
111
112 return 0;
113 }
114
115
pasn_wd_handle_sae_confirm(struct pasn_data * pasn,const u8 * peer_addr,struct wpabuf * wd)116 static int pasn_wd_handle_sae_confirm(struct pasn_data *pasn,
117 const u8 *peer_addr, struct wpabuf *wd)
118 {
119 const u8 *data;
120 size_t buf_len;
121 u16 res, alg, seq, status;
122
123 if (!wd)
124 return -1;
125
126 data = wpabuf_head_u8(wd);
127 buf_len = wpabuf_len(wd);
128
129 if (buf_len < 6) {
130 wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short. len=%zu",
131 buf_len);
132 return -1;
133 }
134
135 alg = WPA_GET_LE16(data);
136 seq = WPA_GET_LE16(data + 2);
137 status = WPA_GET_LE16(data + 4);
138
139 wpa_printf(MSG_DEBUG, "PASN: SAE confirm: alg=%u, seq=%u, status=%u",
140 alg, seq, status);
141
142 if (alg != WLAN_AUTH_SAE || seq != 2 || status != WLAN_STATUS_SUCCESS) {
143 wpa_printf(MSG_DEBUG, "PASN: Dropping peer SAE confirm");
144 return -1;
145 }
146
147 res = sae_check_confirm(&pasn->sae, data + 6, buf_len - 6, NULL);
148 if (res != WLAN_STATUS_SUCCESS) {
149 wpa_printf(MSG_DEBUG, "PASN: SAE failed checking confirm");
150 return -1;
151 }
152
153 pasn->sae.state = SAE_ACCEPTED;
154
155 /*
156 * TODO: Based on on IEEE P802.11az/D2.6, the PMKSA derived with
157 * PASN/SAE should only be allowed with future PASN only. For now do not
158 * restrict this only for PASN.
159 */
160 if (pasn->disable_pmksa_caching)
161 return 0;
162
163 wpa_hexdump_key(MSG_DEBUG, "RSN: Cache PMK from SAE",
164 pasn->sae.pmk, pasn->sae.pmk_len);
165 if (!pasn->sae.akmp)
166 pasn->sae.akmp = WPA_KEY_MGMT_SAE;
167
168 pmksa_cache_auth_add(pasn->pmksa, pasn->sae.pmk, pasn->sae.pmk_len,
169 pasn->sae.pmkid, NULL, 0, pasn->own_addr,
170 peer_addr, 0, NULL, pasn->sae.akmp);
171 return 0;
172 }
173
174
pasn_get_sae_wd(struct pasn_data * pasn)175 static struct wpabuf * pasn_get_sae_wd(struct pasn_data *pasn)
176 {
177 struct wpabuf *buf = NULL;
178 u8 *len_ptr;
179 size_t len;
180
181 /* Need to add the entire Authentication frame body */
182 buf = wpabuf_alloc(8 + SAE_COMMIT_MAX_LEN + 8 + SAE_CONFIRM_MAX_LEN);
183 if (!buf) {
184 wpa_printf(MSG_DEBUG, "PASN: Failed to allocate SAE buffer");
185 return NULL;
186 }
187
188 /* Need to add the entire authentication frame body for the commit */
189 len_ptr = wpabuf_put(buf, 2);
190 wpabuf_put_le16(buf, WLAN_AUTH_SAE);
191 wpabuf_put_le16(buf, 1);
192 wpabuf_put_le16(buf, WLAN_STATUS_SAE_HASH_TO_ELEMENT);
193
194 /* Write the actual commit and update the length accordingly */
195 sae_write_commit(&pasn->sae, buf, NULL, 0);
196 len = wpabuf_len(buf);
197 WPA_PUT_LE16(len_ptr, len - 2);
198
199 /* Need to add the entire Authentication frame body for the confirm */
200 len_ptr = wpabuf_put(buf, 2);
201 wpabuf_put_le16(buf, WLAN_AUTH_SAE);
202 wpabuf_put_le16(buf, 2);
203 wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
204
205 sae_write_confirm(&pasn->sae, buf);
206 WPA_PUT_LE16(len_ptr, wpabuf_len(buf) - len - 2);
207
208 pasn->sae.state = SAE_CONFIRMED;
209
210 return buf;
211 }
212
213 #endif /* CONFIG_SAE */
214
215
216 #ifdef CONFIG_FILS
217
pasn_get_fils_wd(struct pasn_data * pasn)218 static struct wpabuf * pasn_get_fils_wd(struct pasn_data *pasn)
219 {
220 struct pasn_fils *fils = &pasn->fils;
221 struct wpabuf *buf = NULL;
222
223 if (!fils->erp_resp) {
224 wpa_printf(MSG_DEBUG, "PASN: FILS: Missing erp_resp");
225 return NULL;
226 }
227
228 buf = wpabuf_alloc(1500);
229 if (!buf)
230 return NULL;
231
232 /* Add the authentication algorithm */
233 wpabuf_put_le16(buf, WLAN_AUTH_FILS_SK);
234
235 /* Authentication Transaction seq# */
236 wpabuf_put_le16(buf, 2);
237
238 /* Status Code */
239 wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
240
241 /* Own RSNE */
242 wpa_pasn_add_rsne(buf, NULL, pasn->akmp, pasn->cipher);
243
244 /* FILS Nonce */
245 wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
246 wpabuf_put_u8(buf, 1 + FILS_NONCE_LEN);
247 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_NONCE);
248 wpabuf_put_data(buf, fils->anonce, FILS_NONCE_LEN);
249
250 /* FILS Session */
251 wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
252 wpabuf_put_u8(buf, 1 + FILS_SESSION_LEN);
253 wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_SESSION);
254 wpabuf_put_data(buf, fils->session, FILS_SESSION_LEN);
255
256 /* Wrapped Data */
257 wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
258 wpabuf_put_u8(buf, 1 + wpabuf_len(fils->erp_resp));
259 wpabuf_put_u8(buf, WLAN_EID_EXT_WRAPPED_DATA);
260 wpabuf_put_buf(buf, fils->erp_resp);
261
262 return buf;
263 }
264
265 #endif /* CONFIG_FILS */
266
pasn_get_wrapped_data(struct pasn_data * pasn)267 static struct wpabuf * pasn_get_wrapped_data(struct pasn_data *pasn)
268 {
269 switch (pasn->akmp) {
270 case WPA_KEY_MGMT_PASN:
271 /* no wrapped data */
272 return NULL;
273 case WPA_KEY_MGMT_SAE:
274 #ifdef CONFIG_SAE
275 return pasn_get_sae_wd(pasn);
276 #else /* CONFIG_SAE */
277 wpa_printf(MSG_ERROR,
278 "PASN: SAE: Cannot derive wrapped data");
279 return NULL;
280 #endif /* CONFIG_SAE */
281 case WPA_KEY_MGMT_FILS_SHA256:
282 case WPA_KEY_MGMT_FILS_SHA384:
283 #ifdef CONFIG_FILS
284 return pasn_get_fils_wd(pasn);
285 #endif /* CONFIG_FILS */
286 /* fall through */
287 case WPA_KEY_MGMT_FT_PSK:
288 case WPA_KEY_MGMT_FT_IEEE8021X:
289 case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
290 default:
291 wpa_printf(MSG_ERROR,
292 "PASN: TODO: Wrapped data for akmp=0x%x",
293 pasn->akmp);
294 return NULL;
295 }
296 }
297
298
299 static int
pasn_derive_keys(struct pasn_data * pasn,const u8 * own_addr,const u8 * peer_addr,const u8 * cached_pmk,size_t cached_pmk_len,struct wpa_pasn_params_data * pasn_data,struct wpabuf * wrapped_data,struct wpabuf * secret)300 pasn_derive_keys(struct pasn_data *pasn,
301 const u8 *own_addr, const u8 *peer_addr,
302 const u8 *cached_pmk, size_t cached_pmk_len,
303 struct wpa_pasn_params_data *pasn_data,
304 struct wpabuf *wrapped_data,
305 struct wpabuf *secret)
306 {
307 static const u8 pasn_default_pmk[] = {'P', 'M', 'K', 'z'};
308 u8 pmk[PMK_LEN_MAX];
309 u8 pmk_len;
310 int ret;
311
312 os_memset(pmk, 0, sizeof(pmk));
313 pmk_len = 0;
314
315 if (!cached_pmk || !cached_pmk_len)
316 wpa_printf(MSG_DEBUG, "PASN: No valid PMKSA entry");
317
318 if (pasn->akmp == WPA_KEY_MGMT_PASN) {
319 wpa_printf(MSG_DEBUG, "PASN: Using default PMK");
320
321 pmk_len = WPA_PASN_PMK_LEN;
322 os_memcpy(pmk, pasn_default_pmk, sizeof(pasn_default_pmk));
323 } else if (cached_pmk && cached_pmk_len) {
324 wpa_printf(MSG_DEBUG, "PASN: Using PMKSA entry");
325
326 pmk_len = cached_pmk_len;
327 os_memcpy(pmk, cached_pmk, cached_pmk_len);
328 } else {
329 switch (pasn->akmp) {
330 #ifdef CONFIG_SAE
331 case WPA_KEY_MGMT_SAE:
332 if (pasn->sae.state == SAE_COMMITTED) {
333 pmk_len = PMK_LEN;
334 os_memcpy(pmk, pasn->sae.pmk, PMK_LEN);
335 break;
336 }
337 #endif /* CONFIG_SAE */
338 /* fall through */
339 default:
340 /* TODO: Derive PMK based on wrapped data */
341 wpa_printf(MSG_DEBUG,
342 "PASN: Missing PMK derivation");
343 return -1;
344 }
345 }
346
347 pasn->pmk_len = pmk_len;
348 os_memcpy(pasn->pmk, pmk, pmk_len);
349 ret = pasn_pmk_to_ptk(pmk, pmk_len, peer_addr, own_addr,
350 wpabuf_head(secret), wpabuf_len(secret),
351 &pasn->ptk, pasn->akmp,
352 pasn->cipher, pasn->kdk_len);
353 if (ret) {
354 wpa_printf(MSG_DEBUG, "PASN: Failed to derive PTK");
355 return -1;
356 }
357
358 if (pasn->secure_ltf) {
359 ret = wpa_ltf_keyseed(&pasn->ptk, pasn->akmp,
360 pasn->cipher);
361 if (ret) {
362 wpa_printf(MSG_DEBUG,
363 "PASN: Failed to derive LTF keyseed");
364 return -1;
365 }
366 }
367
368 wpa_printf(MSG_DEBUG, "PASN: PTK successfully derived");
369 return 0;
370 }
371
372
handle_auth_pasn_comeback(struct pasn_data * pasn,const u8 * own_addr,const u8 * peer_addr,u16 group)373 static void handle_auth_pasn_comeback(struct pasn_data *pasn,
374 const u8 *own_addr, const u8 *peer_addr,
375 u16 group)
376 {
377 struct wpabuf *buf, *comeback;
378 int ret;
379
380 wpa_printf(MSG_DEBUG,
381 "PASN: Building comeback frame 2. Comeback after=%u",
382 pasn->comeback_after);
383
384 buf = wpabuf_alloc(1500);
385 if (!buf)
386 return;
387
388 wpa_pasn_build_auth_header(buf, pasn->bssid, own_addr, peer_addr, 2,
389 WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY);
390
391 /*
392 * Do not include the group as a part of the token since it is not going
393 * to be used.
394 */
395 comeback = auth_build_token_req(&pasn->last_comeback_key_update,
396 pasn->comeback_key, pasn->comeback_idx,
397 pasn->comeback_pending_idx,
398 sizeof(u16) * COMEBACK_PENDING_IDX_SIZE,
399 0, peer_addr, 0);
400 if (!comeback) {
401 wpa_printf(MSG_DEBUG,
402 "PASN: Failed sending auth with comeback");
403 wpabuf_free(buf);
404 return;
405 }
406
407 wpa_pasn_add_parameter_ie(buf, group,
408 WPA_PASN_WRAPPED_DATA_NO,
409 NULL, 0, comeback,
410 pasn->comeback_after);
411 wpabuf_free(comeback);
412
413 wpa_printf(MSG_DEBUG,
414 "PASN: comeback: STA=" MACSTR, MAC2STR(peer_addr));
415
416 ret = pasn->send_mgmt(pasn->cb_ctx, wpabuf_head_u8(buf),
417 wpabuf_len(buf), 0, 0, 0);
418 if (ret)
419 wpa_printf(MSG_INFO, "PASN: Failed to send comeback frame 2");
420
421 wpabuf_free(buf);
422 }
423
424
handle_auth_pasn_resp(struct pasn_data * pasn,const u8 * own_addr,const u8 * peer_addr,struct rsn_pmksa_cache_entry * pmksa,u16 status)425 int handle_auth_pasn_resp(struct pasn_data *pasn, const u8 *own_addr,
426 const u8 *peer_addr,
427 struct rsn_pmksa_cache_entry *pmksa, u16 status)
428 {
429 struct wpabuf *buf, *pubkey = NULL, *wrapped_data_buf = NULL;
430 struct wpabuf *rsn_buf = NULL;
431 u8 mic[WPA_PASN_MAX_MIC_LEN];
432 u8 mic_len;
433 u8 *ptr;
434 const u8 *frame, *data, *rsn_ie, *rsnxe_ie;
435 u8 *data_buf = NULL;
436 size_t frame_len, data_len;
437 int ret;
438 const u8 *pmkid = NULL;
439
440 wpa_printf(MSG_DEBUG, "PASN: Building frame 2: status=%u", status);
441
442 buf = wpabuf_alloc(1500);
443 if (!buf)
444 goto fail;
445
446 wpa_pasn_build_auth_header(buf, pasn->bssid, own_addr, peer_addr, 2,
447 status);
448
449 if (status != WLAN_STATUS_SUCCESS)
450 goto done;
451
452 if (pmksa && pasn->custom_pmkid_valid)
453 pmkid = pasn->custom_pmkid;
454 else if (pmksa) {
455 pmkid = pmksa->pmkid;
456 #ifdef CONFIG_SAE
457 } else if (pasn->akmp == WPA_KEY_MGMT_SAE) {
458 wpa_printf(MSG_DEBUG, "PASN: Use SAE PMKID");
459 pmkid = pasn->sae.pmkid;
460 #endif /* CONFIG_SAE */
461 #ifdef CONFIG_FILS
462 } else if (pasn->akmp == WPA_KEY_MGMT_FILS_SHA256 ||
463 pasn->akmp == WPA_KEY_MGMT_FILS_SHA384) {
464 wpa_printf(MSG_DEBUG, "PASN: Use FILS ERP PMKID");
465 pmkid = pasn->fils.erp_pmkid;
466 #endif /* CONFIG_FILS */
467 }
468
469 if (wpa_pasn_add_rsne(buf, pmkid,
470 pasn->akmp, pasn->cipher) < 0)
471 goto fail;
472
473 /* No need to derive PMK if PMKSA is given */
474 if (!pmksa)
475 wrapped_data_buf = pasn_get_wrapped_data(pasn);
476 else
477 pasn->wrapped_data_format = WPA_PASN_WRAPPED_DATA_NO;
478
479 /* Get public key */
480 pubkey = crypto_ecdh_get_pubkey(pasn->ecdh, 0);
481 pubkey = wpabuf_zeropad(pubkey,
482 crypto_ecdh_prime_len(pasn->ecdh));
483 if (!pubkey) {
484 wpa_printf(MSG_DEBUG, "PASN: Failed to get pubkey");
485 goto fail;
486 }
487
488 wpa_pasn_add_parameter_ie(buf, pasn->group,
489 pasn->wrapped_data_format,
490 pubkey, true, NULL, 0);
491
492 if (wpa_pasn_add_wrapped_data(buf, wrapped_data_buf) < 0)
493 goto fail;
494
495 wpabuf_free(wrapped_data_buf);
496 wrapped_data_buf = NULL;
497 wpabuf_free(pubkey);
498 pubkey = NULL;
499
500 /* Add RSNXE if needed */
501 rsnxe_ie = pasn->rsnxe_ie;
502 if (rsnxe_ie)
503 wpabuf_put_data(buf, rsnxe_ie, 2 + rsnxe_ie[1]);
504
505 wpa_pasn_add_extra_ies(buf, pasn->extra_ies, pasn->extra_ies_len);
506
507 /* Add the mic */
508 mic_len = pasn_mic_len(pasn->akmp, pasn->cipher);
509 wpabuf_put_u8(buf, WLAN_EID_MIC);
510 wpabuf_put_u8(buf, mic_len);
511 ptr = wpabuf_put(buf, mic_len);
512
513 os_memset(ptr, 0, mic_len);
514
515 frame = wpabuf_head_u8(buf) + IEEE80211_HDRLEN;
516 frame_len = wpabuf_len(buf) - IEEE80211_HDRLEN;
517
518 if (pasn->rsn_ie && pasn->rsn_ie_len) {
519 rsn_ie = pasn->rsn_ie;
520 } else {
521 /*
522 * Note: when pasn->rsn_ie is NULL, it is likely that Beacon
523 * frame RSNE is not initialized. This is possible in case of
524 * PASN authentication used for Wi-Fi Aware for which Beacon
525 * frame RSNE and RSNXE are same as RSNE and RSNXE in the
526 * Authentication frame.
527 */
528 rsn_buf = wpabuf_alloc(500);
529 if (!rsn_buf)
530 goto fail;
531
532 if (wpa_pasn_add_rsne(rsn_buf, pmkid,
533 pasn->akmp, pasn->cipher) < 0)
534 goto fail;
535
536 rsn_ie = wpabuf_head_u8(rsn_buf);
537 }
538
539 /*
540 * Note: wpa_auth_get_wpa_ie() might return not only the RSNE but also
541 * MDE, etc. Thus, do not use the returned length but instead use the
542 * length specified in the IE header.
543 */
544 data_len = rsn_ie[1] + 2;
545 if (rsnxe_ie) {
546 data_buf = os_zalloc(rsn_ie[1] + 2 + rsnxe_ie[1] + 2);
547 if (!data_buf)
548 goto fail;
549
550 os_memcpy(data_buf, rsn_ie, rsn_ie[1] + 2);
551 os_memcpy(data_buf + rsn_ie[1] + 2, rsnxe_ie, rsnxe_ie[1] + 2);
552 data_len += rsnxe_ie[1] + 2;
553 data = data_buf;
554 } else {
555 data = rsn_ie;
556 }
557
558 ret = pasn_mic(pasn->ptk.kck, pasn->akmp, pasn->cipher,
559 own_addr, peer_addr, data, data_len,
560 frame, frame_len, mic);
561 os_free(data_buf);
562 if (ret) {
563 wpa_printf(MSG_DEBUG, "PASN: Frame 3: Failed MIC calculation");
564 goto fail;
565 }
566
567 #ifdef CONFIG_TESTING_OPTIONS
568 if (pasn->corrupt_mic) {
569 wpa_printf(MSG_DEBUG, "PASN: frame 2: Corrupt MIC");
570 mic[0] = ~mic[0];
571 }
572 #endif /* CONFIG_TESTING_OPTIONS */
573
574 os_memcpy(ptr, mic, mic_len);
575
576 done:
577 wpa_printf(MSG_DEBUG,
578 "PASN: Building frame 2: success; resp STA=" MACSTR,
579 MAC2STR(peer_addr));
580
581 ret = pasn->send_mgmt(pasn->cb_ctx, wpabuf_head_u8(buf),
582 wpabuf_len(buf), 0, 0, 0);
583 if (ret)
584 wpa_printf(MSG_INFO, "send_auth_reply: Send failed");
585
586 wpabuf_free(rsn_buf);
587 wpabuf_free(buf);
588 return ret;
589 fail:
590 wpabuf_free(wrapped_data_buf);
591 wpabuf_free(pubkey);
592 wpabuf_free(rsn_buf);
593 wpabuf_free(buf);
594 return -1;
595 }
596
597
handle_auth_pasn_1(struct pasn_data * pasn,const u8 * own_addr,const u8 * peer_addr,const struct ieee80211_mgmt * mgmt,size_t len)598 int handle_auth_pasn_1(struct pasn_data *pasn,
599 const u8 *own_addr, const u8 *peer_addr,
600 const struct ieee80211_mgmt *mgmt, size_t len)
601 {
602 struct ieee802_11_elems elems;
603 struct wpa_ie_data rsn_data;
604 struct wpa_pasn_params_data pasn_params;
605 struct rsn_pmksa_cache_entry *pmksa = NULL;
606 const u8 *cached_pmk = NULL;
607 size_t cached_pmk_len = 0;
608 struct wpabuf *wrapped_data = NULL, *secret = NULL;
609 const int *groups = pasn->pasn_groups;
610 static const int default_groups[] = { 19, 0 };
611 u16 status = WLAN_STATUS_SUCCESS;
612 int ret, inc_y;
613 bool derive_keys;
614 u32 i;
615
616 if (!groups)
617 groups = default_groups;
618
619 if (ieee802_11_parse_elems(mgmt->u.auth.variable,
620 len - offsetof(struct ieee80211_mgmt,
621 u.auth.variable),
622 &elems, 0) == ParseFailed) {
623 wpa_printf(MSG_DEBUG,
624 "PASN: Failed parsing Authentication frame");
625 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
626 goto send_resp;
627 }
628
629 if (!elems.rsn_ie) {
630 wpa_printf(MSG_DEBUG, "PASN: No RSNE");
631 status = WLAN_STATUS_INVALID_RSNIE;
632 goto send_resp;
633 }
634
635 ret = wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
636 &rsn_data);
637 if (ret) {
638 wpa_printf(MSG_DEBUG, "PASN: Failed parsing RSNE");
639 status = WLAN_STATUS_INVALID_RSNIE;
640 goto send_resp;
641 }
642
643 ret = wpa_pasn_validate_rsne(&rsn_data);
644 if (ret) {
645 wpa_printf(MSG_DEBUG, "PASN: Failed validating RSNE");
646 status = WLAN_STATUS_INVALID_RSNIE;
647 goto send_resp;
648 }
649
650 if (!(rsn_data.key_mgmt & pasn->wpa_key_mgmt) ||
651 !(rsn_data.pairwise_cipher & pasn->rsn_pairwise)) {
652 wpa_printf(MSG_DEBUG, "PASN: Mismatch in AKMP/cipher");
653 status = WLAN_STATUS_INVALID_RSNIE;
654 goto send_resp;
655 }
656
657 pasn->akmp = rsn_data.key_mgmt;
658 pasn->cipher = rsn_data.pairwise_cipher;
659
660 if (pasn->derive_kdk &&
661 ieee802_11_rsnx_capab_len(elems.rsnxe, elems.rsnxe_len,
662 WLAN_RSNX_CAPAB_SECURE_LTF))
663 pasn->secure_ltf = true;
664
665 if (pasn->derive_kdk)
666 pasn->kdk_len = WPA_KDK_MAX_LEN;
667 else
668 pasn->kdk_len = 0;
669
670 wpa_printf(MSG_DEBUG, "PASN: kdk_len=%zu", pasn->kdk_len);
671
672 if (!elems.pasn_params || !elems.pasn_params_len) {
673 wpa_printf(MSG_DEBUG,
674 "PASN: No PASN Parameters element found");
675 status = WLAN_STATUS_INVALID_PARAMETERS;
676 goto send_resp;
677 }
678
679 ret = wpa_pasn_parse_parameter_ie(elems.pasn_params - 3,
680 elems.pasn_params_len + 3,
681 false, &pasn_params);
682 if (ret) {
683 wpa_printf(MSG_DEBUG,
684 "PASN: Failed validation of PASN Parameters IE");
685 status = WLAN_STATUS_INVALID_PARAMETERS;
686 goto send_resp;
687 }
688
689 for (i = 0; groups[i] > 0 && groups[i] != pasn_params.group; i++)
690 ;
691
692 if (!pasn_params.group || groups[i] != pasn_params.group) {
693 wpa_printf(MSG_DEBUG, "PASN: Requested group=%hu not allowed",
694 pasn_params.group);
695 status = WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
696 goto send_resp;
697 }
698
699 if (!pasn_params.pubkey || !pasn_params.pubkey_len) {
700 wpa_printf(MSG_DEBUG, "PASN: Invalid public key");
701 status = WLAN_STATUS_INVALID_PARAMETERS;
702 goto send_resp;
703 }
704
705 if (pasn_params.comeback) {
706 wpa_printf(MSG_DEBUG, "PASN: Checking peer comeback token");
707
708 ret = check_comeback_token(pasn->comeback_key,
709 pasn->comeback_pending_idx,
710 peer_addr,
711 pasn_params.comeback,
712 pasn_params.comeback_len);
713
714 if (ret) {
715 wpa_printf(MSG_DEBUG, "PASN: Invalid comeback token");
716 status = WLAN_STATUS_INVALID_PARAMETERS;
717 goto send_resp;
718 }
719 } else if (pasn->use_anti_clogging) {
720 wpa_printf(MSG_DEBUG, "PASN: Respond with comeback");
721 handle_auth_pasn_comeback(pasn, own_addr, peer_addr,
722 pasn_params.group);
723 return -1;
724 }
725
726 pasn->ecdh = crypto_ecdh_init(pasn_params.group);
727 if (!pasn->ecdh) {
728 wpa_printf(MSG_DEBUG, "PASN: Failed to init ECDH");
729 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
730 goto send_resp;
731 }
732
733 pasn->group = pasn_params.group;
734
735 if (pasn_params.pubkey[0] == WPA_PASN_PUBKEY_UNCOMPRESSED) {
736 inc_y = 1;
737 } else if (pasn_params.pubkey[0] == WPA_PASN_PUBKEY_COMPRESSED_0 ||
738 pasn_params.pubkey[0] == WPA_PASN_PUBKEY_COMPRESSED_1) {
739 inc_y = 0;
740 } else {
741 wpa_printf(MSG_DEBUG,
742 "PASN: Invalid first octet in pubkey=0x%x",
743 pasn_params.pubkey[0]);
744 status = WLAN_STATUS_INVALID_PUBLIC_KEY;
745 goto send_resp;
746 }
747
748 secret = crypto_ecdh_set_peerkey(pasn->ecdh, inc_y,
749 pasn_params.pubkey + 1,
750 pasn_params.pubkey_len - 1);
751 if (!secret) {
752 wpa_printf(MSG_DEBUG, "PASN: Failed to derive shared secret");
753 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
754 goto send_resp;
755 }
756
757 if (!pasn->noauth && pasn->akmp == WPA_KEY_MGMT_PASN) {
758 wpa_printf(MSG_DEBUG, "PASN: Refuse PASN-UNAUTH");
759 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
760 goto send_resp;
761 }
762
763 derive_keys = true;
764 if (pasn_params.wrapped_data_format != WPA_PASN_WRAPPED_DATA_NO) {
765 wrapped_data = ieee802_11_defrag(elems.wrapped_data,
766 elems.wrapped_data_len, true);
767 if (!wrapped_data) {
768 wpa_printf(MSG_DEBUG, "PASN: Missing wrapped data");
769 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
770 goto send_resp;
771 }
772
773 #ifdef CONFIG_SAE
774 if (pasn->akmp == WPA_KEY_MGMT_SAE) {
775 ret = pasn_wd_handle_sae_commit(pasn, own_addr,
776 peer_addr,
777 wrapped_data);
778 if (ret) {
779 wpa_printf(MSG_DEBUG,
780 "PASN: Failed processing SAE commit");
781 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
782 goto send_resp;
783 }
784 }
785 #endif /* CONFIG_SAE */
786 #ifdef CONFIG_FILS
787 if (pasn->akmp == WPA_KEY_MGMT_FILS_SHA256 ||
788 pasn->akmp == WPA_KEY_MGMT_FILS_SHA384) {
789 if (!pasn->fils_wd_valid) {
790 wpa_printf(MSG_DEBUG,
791 "PASN: Invalid FILS wrapped data");
792 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
793 goto send_resp;
794 }
795
796 wpa_printf(MSG_DEBUG,
797 "PASN: FILS: Pending AS response");
798
799 /*
800 * With PASN/FILS, keys can be derived only after a
801 * response from the AS is processed.
802 */
803 derive_keys = false;
804 }
805 #endif /* CONFIG_FILS */
806 }
807
808 pasn->wrapped_data_format = pasn_params.wrapped_data_format;
809
810 ret = pasn_auth_frame_hash(pasn->akmp, pasn->cipher,
811 ((const u8 *) mgmt) + IEEE80211_HDRLEN,
812 len - IEEE80211_HDRLEN, pasn->hash);
813 if (ret) {
814 wpa_printf(MSG_DEBUG, "PASN: Failed to compute hash");
815 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
816 goto send_resp;
817 }
818
819 if (!derive_keys) {
820 wpa_printf(MSG_DEBUG, "PASN: Storing secret");
821 pasn->secret = secret;
822 wpabuf_free(wrapped_data);
823 return 0;
824 }
825
826 if (rsn_data.num_pmkid) {
827 if (wpa_key_mgmt_ft(pasn->akmp)) {
828 #ifdef CONFIG_IEEE80211R_AP
829 wpa_printf(MSG_DEBUG, "PASN: FT: Fetch PMK-R1");
830
831 if (!pasn->pmk_r1_len) {
832 wpa_printf(MSG_DEBUG,
833 "PASN: FT: Failed getting PMK-R1");
834 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
835 goto send_resp;
836 }
837 cached_pmk = pasn->pmk_r1;
838 cached_pmk_len = pasn->pmk_r1_len;
839 #else /* CONFIG_IEEE80211R_AP */
840 wpa_printf(MSG_DEBUG, "PASN: FT: Not supported");
841 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
842 goto send_resp;
843 #endif /* CONFIG_IEEE80211R_AP */
844 } else {
845 wpa_printf(MSG_DEBUG, "PASN: Try to find PMKSA entry");
846
847 if (pasn->pmksa) {
848 const u8 *pmkid = NULL;
849
850 if (pasn->custom_pmkid_valid) {
851 ret = pasn->validate_custom_pmkid(
852 pasn->cb_ctx, peer_addr,
853 rsn_data.pmkid);
854 if (ret) {
855 wpa_printf(MSG_DEBUG,
856 "PASN: Failed custom PMKID validation");
857 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
858 goto send_resp;
859 }
860 } else {
861 pmkid = rsn_data.pmkid;
862 }
863
864 pmksa = pmksa_cache_auth_get(pasn->pmksa,
865 peer_addr,
866 pmkid);
867 if (pmksa) {
868 cached_pmk = pmksa->pmk;
869 cached_pmk_len = pmksa->pmk_len;
870 }
871 }
872 }
873 } else {
874 wpa_printf(MSG_DEBUG, "PASN: No PMKID specified");
875 }
876
877 ret = pasn_derive_keys(pasn, own_addr, peer_addr,
878 cached_pmk, cached_pmk_len,
879 &pasn_params, wrapped_data, secret);
880 if (ret) {
881 wpa_printf(MSG_DEBUG, "PASN: Failed to derive keys");
882 status = WLAN_STATUS_PASN_BASE_AKMP_FAILED;
883 goto send_resp;
884 }
885
886 ret = pasn_auth_frame_hash(pasn->akmp, pasn->cipher,
887 ((const u8 *) mgmt) + IEEE80211_HDRLEN,
888 len - IEEE80211_HDRLEN, pasn->hash);
889 if (ret) {
890 wpa_printf(MSG_DEBUG, "PASN: Failed to compute hash");
891 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
892 }
893
894 send_resp:
895 ret = handle_auth_pasn_resp(pasn, own_addr, peer_addr, pmksa, status);
896 if (ret) {
897 wpa_printf(MSG_DEBUG, "PASN: Failed to send response");
898 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
899 } else {
900 wpa_printf(MSG_DEBUG,
901 "PASN: Success handling transaction == 1");
902 }
903
904 wpabuf_free(secret);
905 wpabuf_free(wrapped_data);
906
907 if (status != WLAN_STATUS_SUCCESS)
908 return -1;
909
910 return 0;
911 }
912
913
handle_auth_pasn_3(struct pasn_data * pasn,const u8 * own_addr,const u8 * peer_addr,const struct ieee80211_mgmt * mgmt,size_t len)914 int handle_auth_pasn_3(struct pasn_data *pasn, const u8 *own_addr,
915 const u8 *peer_addr,
916 const struct ieee80211_mgmt *mgmt, size_t len)
917 {
918 struct ieee802_11_elems elems;
919 struct wpa_pasn_params_data pasn_params;
920 struct wpabuf *wrapped_data = NULL;
921 u8 mic[WPA_PASN_MAX_MIC_LEN], out_mic[WPA_PASN_MAX_MIC_LEN];
922 u8 mic_len;
923 int ret;
924 u8 *copy = NULL;
925 size_t copy_len, mic_offset;
926
927 if (ieee802_11_parse_elems(mgmt->u.auth.variable,
928 len - offsetof(struct ieee80211_mgmt,
929 u.auth.variable),
930 &elems, 0) == ParseFailed) {
931 wpa_printf(MSG_DEBUG,
932 "PASN: Failed parsing Authentication frame");
933 goto fail;
934 }
935
936 /* Check that the MIC IE exists. Save it and zero out the memory. */
937 mic_len = pasn_mic_len(pasn->akmp, pasn->cipher);
938 if (!elems.mic || elems.mic_len != mic_len) {
939 wpa_printf(MSG_DEBUG,
940 "PASN: Invalid MIC. Expecting len=%u", mic_len);
941 goto fail;
942 }
943 os_memcpy(mic, elems.mic, mic_len);
944
945 if (!elems.pasn_params || !elems.pasn_params_len) {
946 wpa_printf(MSG_DEBUG,
947 "PASN: No PASN Parameters element found");
948 goto fail;
949 }
950
951 ret = wpa_pasn_parse_parameter_ie(elems.pasn_params - 3,
952 elems.pasn_params_len + 3,
953 false, &pasn_params);
954 if (ret) {
955 wpa_printf(MSG_DEBUG,
956 "PASN: Failed validation of PASN Parameters IE");
957 goto fail;
958 }
959
960 if (pasn_params.pubkey || pasn_params.pubkey_len) {
961 wpa_printf(MSG_DEBUG,
962 "PASN: Public key should not be included");
963 goto fail;
964 }
965
966 /* Verify the MIC */
967 copy_len = len - offsetof(struct ieee80211_mgmt, u.auth);
968 mic_offset = elems.mic - (const u8 *) &mgmt->u.auth;
969 copy_len = len - offsetof(struct ieee80211_mgmt, u.auth);
970 if (mic_offset + mic_len > copy_len)
971 goto fail;
972 copy = os_memdup(&mgmt->u.auth, copy_len);
973 if (!copy)
974 goto fail;
975 os_memset(copy + mic_offset, 0, mic_len);
976 ret = pasn_mic(pasn->ptk.kck, pasn->akmp, pasn->cipher,
977 peer_addr, own_addr,
978 pasn->hash, mic_len * 2,
979 copy, copy_len, out_mic);
980 os_free(copy);
981 copy = NULL;
982
983 wpa_hexdump_key(MSG_DEBUG, "PASN: Frame MIC", mic, mic_len);
984 if (ret || os_memcmp(mic, out_mic, mic_len) != 0) {
985 wpa_printf(MSG_DEBUG, "PASN: Failed MIC verification");
986 goto fail;
987 }
988
989 if (pasn_params.wrapped_data_format != WPA_PASN_WRAPPED_DATA_NO) {
990 wrapped_data = ieee802_11_defrag(elems.wrapped_data,
991 elems.wrapped_data_len,
992 true);
993
994 if (!wrapped_data) {
995 wpa_printf(MSG_DEBUG, "PASN: Missing wrapped data");
996 goto fail;
997 }
998
999 #ifdef CONFIG_SAE
1000 if (pasn->akmp == WPA_KEY_MGMT_SAE) {
1001 ret = pasn_wd_handle_sae_confirm(pasn, peer_addr,
1002 wrapped_data);
1003 if (ret) {
1004 wpa_printf(MSG_DEBUG,
1005 "PASN: Failed processing SAE confirm");
1006 wpabuf_free(wrapped_data);
1007 goto fail;
1008 }
1009 }
1010 #endif /* CONFIG_SAE */
1011 #ifdef CONFIG_FILS
1012 if (pasn->akmp == WPA_KEY_MGMT_FILS_SHA256 ||
1013 pasn->akmp == WPA_KEY_MGMT_FILS_SHA384) {
1014 if (wrapped_data) {
1015 wpa_printf(MSG_DEBUG,
1016 "PASN: FILS: Ignore wrapped data");
1017 }
1018 }
1019 #endif /* CONFIG_FILS */
1020 wpabuf_free(wrapped_data);
1021 }
1022
1023 wpa_printf(MSG_INFO,
1024 "PASN: Success handling transaction == 3. Store PTK");
1025 return 0;
1026
1027 fail:
1028 os_free(copy);
1029 return -1;
1030 }
1031
1032 #endif /* CONFIG_PASN */
1033