1 /*
2  * hostapd / IEEE 802.11 Management
3  * Copyright (c) 2002-2017, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "utils/includes.h"
10 
11 #ifndef CONFIG_NATIVE_WINDOWS
12 
13 #include "utils/common.h"
14 #include "utils/eloop.h"
15 #include "crypto/crypto.h"
16 #include "crypto/sha256.h"
17 #include "crypto/sha384.h"
18 #include "crypto/sha512.h"
19 #include "crypto/random.h"
20 #include "common/ieee802_11_defs.h"
21 #include "common/ieee802_11_common.h"
22 #include "common/wpa_ctrl.h"
23 #include "common/sae.h"
24 #include "common/dpp.h"
25 #include "common/ocv.h"
26 #include "common/wpa_common.h"
27 #include "common/wpa_ctrl.h"
28 #include "common/ptksa_cache.h"
29 #include "radius/radius.h"
30 #include "radius/radius_client.h"
31 #include "p2p/p2p.h"
32 #include "wps/wps.h"
33 #include "fst/fst.h"
34 #include "hostapd.h"
35 #include "beacon.h"
36 #include "ieee802_11_auth.h"
37 #include "sta_info.h"
38 #include "ieee802_1x.h"
39 #include "wpa_auth.h"
40 #include "pmksa_cache_auth.h"
41 #include "wmm.h"
42 #include "ap_list.h"
43 #include "accounting.h"
44 #include "ap_config.h"
45 #include "ap_mlme.h"
46 #include "p2p_hostapd.h"
47 #include "ap_drv_ops.h"
48 #include "wnm_ap.h"
49 #include "hw_features.h"
50 #include "ieee802_11.h"
51 #include "dfs.h"
52 #include "mbo_ap.h"
53 #include "rrm.h"
54 #include "taxonomy.h"
55 #include "fils_hlp.h"
56 #include "dpp_hostapd.h"
57 #include "gas_query_ap.h"
58 #include "comeback_token.h"
59 #include "nan_usd_ap.h"
60 #include "pasn/pasn_common.h"
61 
62 
63 #ifdef CONFIG_FILS
64 static struct wpabuf *
65 prepare_auth_resp_fils(struct hostapd_data *hapd,
66                            struct sta_info *sta, u16 *resp,
67                            struct rsn_pmksa_cache_entry *pmksa,
68                            struct wpabuf *erp_resp,
69                            const u8 *msk, size_t msk_len,
70                            int *is_pub);
71 #endif /* CONFIG_FILS */
72 
73 #ifdef CONFIG_PASN
74 #ifdef CONFIG_FILS
75 
76 static void pasn_fils_auth_resp(struct hostapd_data *hapd,
77                                         struct sta_info *sta, u16 status,
78                                         struct wpabuf *erp_resp,
79                                         const u8 *msk, size_t msk_len);
80 
81 #endif /* CONFIG_FILS */
82 #endif /* CONFIG_PASN */
83 
84 static void handle_auth(struct hostapd_data *hapd,
85                               const struct ieee80211_mgmt *mgmt, size_t len,
86                               int rssi, int from_queue);
87 static int add_associated_sta(struct hostapd_data *hapd,
88                                     struct sta_info *sta, int reassoc);
89 
90 
hostapd_eid_multi_ap(struct hostapd_data * hapd,u8 * eid,size_t len)91 static u8 * hostapd_eid_multi_ap(struct hostapd_data *hapd, u8 *eid, size_t len)
92 {
93           struct multi_ap_params multi_ap = { 0 };
94 
95           if (!hapd->conf->multi_ap)
96                     return eid;
97 
98           if (hapd->conf->multi_ap & BACKHAUL_BSS)
99                     multi_ap.capability |= MULTI_AP_BACKHAUL_BSS;
100           if (hapd->conf->multi_ap & FRONTHAUL_BSS)
101                     multi_ap.capability |= MULTI_AP_FRONTHAUL_BSS;
102 
103           if (hapd->conf->multi_ap_client_disallow &
104               PROFILE1_CLIENT_ASSOC_DISALLOW)
105                     multi_ap.capability |=
106                               MULTI_AP_PROFILE1_BACKHAUL_STA_DISALLOWED;
107           if (hapd->conf->multi_ap_client_disallow &
108               PROFILE2_CLIENT_ASSOC_DISALLOW)
109                     multi_ap.capability |=
110                               MULTI_AP_PROFILE2_BACKHAUL_STA_DISALLOWED;
111 
112           multi_ap.profile = hapd->conf->multi_ap_profile;
113           multi_ap.vlanid = hapd->conf->multi_ap_vlanid;
114 
115           return eid + add_multi_ap_ie(eid, len, &multi_ap);
116 }
117 
118 
hostapd_eid_supp_rates(struct hostapd_data * hapd,u8 * eid)119 u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
120 {
121           u8 *pos = eid;
122           int i, num, count;
123           int h2e_required;
124 
125           if (hapd->iface->current_rates == NULL)
126                     return eid;
127 
128           *pos++ = WLAN_EID_SUPP_RATES;
129           num = hapd->iface->num_rates;
130           if (hapd->iconf->ieee80211n && hapd->iconf->require_ht)
131                     num++;
132           if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
133                     num++;
134 #ifdef CONFIG_IEEE80211AX
135           if (hapd->iconf->ieee80211ax && hapd->iconf->require_he)
136                     num++;
137 #endif /* CONFIG_IEEE80211AX */
138           h2e_required = (hapd->conf->sae_pwe == SAE_PWE_HASH_TO_ELEMENT ||
139                               hostapd_sae_pw_id_in_use(hapd->conf) == 2) &&
140                     hapd->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK &&
141                     wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt);
142           if (h2e_required)
143                     num++;
144           if (num > 8) {
145                     /* rest of the rates are encoded in Extended supported
146                      * rates element */
147                     num = 8;
148           }
149 
150           *pos++ = num;
151           for (i = 0, count = 0; i < hapd->iface->num_rates && count < num;
152                i++) {
153                     count++;
154                     *pos = hapd->iface->current_rates[i].rate / 5;
155                     if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)
156                               *pos |= 0x80;
157                     pos++;
158           }
159 
160           if (hapd->iconf->ieee80211n && hapd->iconf->require_ht && count < 8) {
161                     count++;
162                     *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY;
163           }
164 
165           if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht && count < 8) {
166                     count++;
167                     *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
168           }
169 
170 #ifdef CONFIG_IEEE80211AX
171           if (hapd->iconf->ieee80211ax && hapd->iconf->require_he && count < 8) {
172                     count++;
173                     *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HE_PHY;
174           }
175 #endif /* CONFIG_IEEE80211AX */
176 
177           if (h2e_required && count < 8) {
178                     count++;
179                     *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY;
180           }
181 
182           return pos;
183 }
184 
185 
hostapd_eid_ext_supp_rates(struct hostapd_data * hapd,u8 * eid)186 u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid)
187 {
188           u8 *pos = eid;
189           int i, num, count;
190           int h2e_required;
191 
192           hapd->conf->xrates_supported = false;
193           if (hapd->iface->current_rates == NULL)
194                     return eid;
195 
196           num = hapd->iface->num_rates;
197           if (hapd->iconf->ieee80211n && hapd->iconf->require_ht)
198                     num++;
199           if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
200                     num++;
201 #ifdef CONFIG_IEEE80211AX
202           if (hapd->iconf->ieee80211ax && hapd->iconf->require_he)
203                     num++;
204 #endif /* CONFIG_IEEE80211AX */
205           h2e_required = (hapd->conf->sae_pwe == SAE_PWE_HASH_TO_ELEMENT ||
206                               hostapd_sae_pw_id_in_use(hapd->conf) == 2) &&
207                     hapd->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK &&
208                     wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt);
209           if (h2e_required)
210                     num++;
211           if (num <= 8)
212                     return eid;
213           num -= 8;
214 
215           *pos++ = WLAN_EID_EXT_SUPP_RATES;
216           *pos++ = num;
217           for (i = 0, count = 0; i < hapd->iface->num_rates && count < num + 8;
218                i++) {
219                     count++;
220                     if (count <= 8)
221                               continue; /* already in SuppRates IE */
222                     *pos = hapd->iface->current_rates[i].rate / 5;
223                     if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)
224                               *pos |= 0x80;
225                     pos++;
226           }
227 
228           if (hapd->iconf->ieee80211n && hapd->iconf->require_ht) {
229                     count++;
230                     if (count > 8)
231                               *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY;
232           }
233 
234           if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht) {
235                     count++;
236                     if (count > 8)
237                               *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
238           }
239 
240 #ifdef CONFIG_IEEE80211AX
241           if (hapd->iconf->ieee80211ax && hapd->iconf->require_he) {
242                     count++;
243                     if (count > 8)
244                               *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HE_PHY;
245           }
246 #endif /* CONFIG_IEEE80211AX */
247 
248           if (h2e_required) {
249                     count++;
250                     if (count > 8)
251                               *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY;
252           }
253 
254           hapd->conf->xrates_supported = true;
255           return pos;
256 }
257 
258 
hostapd_eid_rm_enabled_capab(struct hostapd_data * hapd,u8 * eid,size_t len)259 u8 * hostapd_eid_rm_enabled_capab(struct hostapd_data *hapd, u8 *eid,
260                                           size_t len)
261 {
262           size_t i;
263 
264           for (i = 0; i < RRM_CAPABILITIES_IE_LEN; i++) {
265                     if (hapd->conf->radio_measurements[i])
266                               break;
267           }
268 
269           if (i == RRM_CAPABILITIES_IE_LEN || len < 2 + RRM_CAPABILITIES_IE_LEN)
270                     return eid;
271 
272           *eid++ = WLAN_EID_RRM_ENABLED_CAPABILITIES;
273           *eid++ = RRM_CAPABILITIES_IE_LEN;
274           os_memcpy(eid, hapd->conf->radio_measurements, RRM_CAPABILITIES_IE_LEN);
275 
276           return eid + RRM_CAPABILITIES_IE_LEN;
277 }
278 
279 
hostapd_own_capab_info(struct hostapd_data * hapd)280 u16 hostapd_own_capab_info(struct hostapd_data *hapd)
281 {
282           int capab = WLAN_CAPABILITY_ESS;
283           int privacy = 0;
284           int dfs;
285           int i;
286 
287           /* Check if any of configured channels require DFS */
288           dfs = hostapd_is_dfs_required(hapd->iface);
289           if (dfs < 0) {
290                     wpa_printf(MSG_WARNING, "Failed to check if DFS is required; ret=%d",
291                                  dfs);
292                     dfs = 0;
293           }
294 
295           if (hapd->iface->num_sta_no_short_preamble == 0 &&
296               hapd->iconf->preamble == SHORT_PREAMBLE)
297                     capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
298 
299 #ifdef CONFIG_WEP
300           privacy = hapd->conf->ssid.wep.keys_set;
301 
302           if (hapd->conf->ieee802_1x &&
303               (hapd->conf->default_wep_key_len ||
304                hapd->conf->individual_wep_key_len))
305                     privacy = 1;
306 #endif /* CONFIG_WEP */
307 
308           if (hapd->conf->wpa)
309                     privacy = 1;
310 
311 #ifdef CONFIG_HS20
312           if (hapd->conf->osen)
313                     privacy = 1;
314 #endif /* CONFIG_HS20 */
315 
316           if (privacy)
317                     capab |= WLAN_CAPABILITY_PRIVACY;
318 
319           if (hapd->iface->current_mode &&
320               hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G &&
321               hapd->iface->num_sta_no_short_slot_time == 0)
322                     capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
323 
324           /*
325            * Currently, Spectrum Management capability bit is set when directly
326            * requested in configuration by spectrum_mgmt_required or when AP is
327            * running on DFS channel.
328            * TODO: Also consider driver support for TPC to set Spectrum Mgmt bit
329            */
330           if (hapd->iface->current_mode &&
331               hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
332               (hapd->iconf->spectrum_mgmt_required || dfs))
333                     capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
334 
335           for (i = 0; i < RRM_CAPABILITIES_IE_LEN; i++) {
336                     if (hapd->conf->radio_measurements[i]) {
337                               capab |= IEEE80211_CAP_RRM;
338                               break;
339                     }
340           }
341 
342           return capab;
343 }
344 
345 
346 #ifdef CONFIG_WEP
347 #ifndef CONFIG_NO_RC4
auth_shared_key(struct hostapd_data * hapd,struct sta_info * sta,u16 auth_transaction,const u8 * challenge,int iswep)348 static u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta,
349                                  u16 auth_transaction, const u8 *challenge,
350                                  int iswep)
351 {
352           hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
353                            HOSTAPD_LEVEL_DEBUG,
354                            "authentication (shared key, transaction %d)",
355                            auth_transaction);
356 
357           if (auth_transaction == 1) {
358                     if (!sta->challenge) {
359                               /* Generate a pseudo-random challenge */
360                               u8 key[8];
361 
362                               sta->challenge = os_zalloc(WLAN_AUTH_CHALLENGE_LEN);
363                               if (sta->challenge == NULL)
364                                         return WLAN_STATUS_UNSPECIFIED_FAILURE;
365 
366                               if (os_get_random(key, sizeof(key)) < 0) {
367                                         os_free(sta->challenge);
368                                         sta->challenge = NULL;
369                                         return WLAN_STATUS_UNSPECIFIED_FAILURE;
370                               }
371 
372                               rc4_skip(key, sizeof(key), 0,
373                                          sta->challenge, WLAN_AUTH_CHALLENGE_LEN);
374                     }
375                     return 0;
376           }
377 
378           if (auth_transaction != 3)
379                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
380 
381           /* Transaction 3 */
382           if (!iswep || !sta->challenge || !challenge ||
383               os_memcmp_const(sta->challenge, challenge,
384                                   WLAN_AUTH_CHALLENGE_LEN)) {
385                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
386                                      HOSTAPD_LEVEL_INFO,
387                                      "shared key authentication - invalid "
388                                      "challenge-response");
389                     return WLAN_STATUS_CHALLENGE_FAIL;
390           }
391 
392           hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
393                            HOSTAPD_LEVEL_DEBUG,
394                            "authentication OK (shared key)");
395           sta->flags |= WLAN_STA_AUTH;
396           wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
397           os_free(sta->challenge);
398           sta->challenge = NULL;
399 
400           return 0;
401 }
402 #endif /* CONFIG_NO_RC4 */
403 #endif /* CONFIG_WEP */
404 
405 
send_auth_reply(struct hostapd_data * hapd,struct sta_info * sta,const u8 * dst,u16 auth_alg,u16 auth_transaction,u16 resp,const u8 * ies,size_t ies_len,const char * dbg)406 static int send_auth_reply(struct hostapd_data *hapd, struct sta_info *sta,
407                                  const u8 *dst,
408                                  u16 auth_alg, u16 auth_transaction, u16 resp,
409                                  const u8 *ies, size_t ies_len, const char *dbg)
410 {
411           struct ieee80211_mgmt *reply;
412           u8 *buf;
413           size_t rlen;
414           int reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE;
415           const u8 *sa = hapd->own_addr;
416           struct wpabuf *ml_resp = NULL;
417 
418 #ifdef CONFIG_IEEE80211BE
419           if (ap_sta_is_mld(hapd, sta)) {
420                     ml_resp = hostapd_ml_auth_resp(hapd);
421                     if (!ml_resp)
422                               return -1;
423           }
424 #endif /* CONFIG_IEEE80211BE */
425 
426           rlen = IEEE80211_HDRLEN + sizeof(reply->u.auth) + ies_len;
427           if (ml_resp)
428                     rlen += wpabuf_len(ml_resp);
429           buf = os_zalloc(rlen);
430           if (!buf) {
431                     wpabuf_free(ml_resp);
432                     return -1;
433           }
434 
435           reply = (struct ieee80211_mgmt *) buf;
436           reply->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
437                                                       WLAN_FC_STYPE_AUTH);
438           os_memcpy(reply->da, dst, ETH_ALEN);
439           os_memcpy(reply->sa, sa, ETH_ALEN);
440           os_memcpy(reply->bssid, sa, ETH_ALEN);
441 
442           reply->u.auth.auth_alg = host_to_le16(auth_alg);
443           reply->u.auth.auth_transaction = host_to_le16(auth_transaction);
444           reply->u.auth.status_code = host_to_le16(resp);
445 
446           if (ies && ies_len)
447                     os_memcpy(reply->u.auth.variable, ies, ies_len);
448 
449 #ifdef CONFIG_IEEE80211BE
450           if (ml_resp)
451                     os_memcpy(reply->u.auth.variable + ies_len,
452                                 wpabuf_head(ml_resp), wpabuf_len(ml_resp));
453 
454           wpabuf_free(ml_resp);
455 #endif /* CONFIG_IEEE80211BE */
456 
457           wpa_printf(MSG_DEBUG, "authentication reply: STA=" MACSTR
458                        " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu) (dbg=%s)",
459                        MAC2STR(dst), auth_alg, auth_transaction,
460                        resp, (unsigned long) ies_len, dbg);
461 #ifdef CONFIG_TESTING_OPTIONS
462 #ifdef CONFIG_SAE
463           if (hapd->conf->sae_confirm_immediate == 2 &&
464               auth_alg == WLAN_AUTH_SAE) {
465                     if (auth_transaction == 1 && sta &&
466                         (resp == WLAN_STATUS_SUCCESS ||
467                          resp == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
468                          resp == WLAN_STATUS_SAE_PK)) {
469                               wpa_printf(MSG_DEBUG,
470                                            "TESTING: Postpone SAE Commit transmission until Confirm is ready");
471                               os_free(sta->sae_postponed_commit);
472                               sta->sae_postponed_commit = buf;
473                               sta->sae_postponed_commit_len = rlen;
474                               return WLAN_STATUS_SUCCESS;
475                     }
476 
477                     if (auth_transaction == 2 && sta && sta->sae_postponed_commit) {
478                               wpa_printf(MSG_DEBUG,
479                                            "TESTING: Send postponed SAE Commit first, immediately followed by SAE Confirm");
480                               if (hostapd_drv_send_mlme(hapd,
481                                                               sta->sae_postponed_commit,
482                                                               sta->sae_postponed_commit_len,
483                                                               0, NULL, 0, 0) < 0)
484                                         wpa_printf(MSG_INFO, "send_auth_reply: send failed");
485                               os_free(sta->sae_postponed_commit);
486                               sta->sae_postponed_commit = NULL;
487                               sta->sae_postponed_commit_len = 0;
488                     }
489           }
490 #endif /* CONFIG_SAE */
491 #endif /* CONFIG_TESTING_OPTIONS */
492           if (hostapd_drv_send_mlme(hapd, reply, rlen, 0, NULL, 0, 0) < 0)
493                     wpa_printf(MSG_INFO, "send_auth_reply: send failed");
494           else
495                     reply_res = WLAN_STATUS_SUCCESS;
496 
497           os_free(buf);
498 
499           return reply_res;
500 }
501 
502 
503 #ifdef CONFIG_IEEE80211R_AP
handle_auth_ft_finish(void * ctx,const u8 * dst,u16 auth_transaction,u16 status,const u8 * ies,size_t ies_len)504 static void handle_auth_ft_finish(void *ctx, const u8 *dst,
505                                           u16 auth_transaction, u16 status,
506                                           const u8 *ies, size_t ies_len)
507 {
508           struct hostapd_data *hapd = ctx;
509           struct sta_info *sta;
510           int reply_res;
511 
512           reply_res = send_auth_reply(hapd, NULL, dst, WLAN_AUTH_FT,
513                                             auth_transaction, status, ies, ies_len,
514                                             "auth-ft-finish");
515 
516           sta = ap_get_sta(hapd, dst);
517           if (sta == NULL)
518                     return;
519 
520           if (sta->added_unassoc && (reply_res != WLAN_STATUS_SUCCESS ||
521                                            status != WLAN_STATUS_SUCCESS)) {
522                     hostapd_drv_sta_remove(hapd, sta->addr);
523                     sta->added_unassoc = 0;
524                     return;
525           }
526 
527           if (status != WLAN_STATUS_SUCCESS)
528                     return;
529 
530           hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211,
531                            HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)");
532           sta->flags |= WLAN_STA_AUTH;
533           mlme_authenticate_indication(hapd, sta);
534 }
535 #endif /* CONFIG_IEEE80211R_AP */
536 
537 
538 #ifdef CONFIG_SAE
539 
sae_set_state(struct sta_info * sta,enum sae_state state,const char * reason)540 static void sae_set_state(struct sta_info *sta, enum sae_state state,
541                                 const char *reason)
542 {
543           wpa_printf(MSG_DEBUG, "SAE: State %s -> %s for peer " MACSTR " (%s)",
544                        sae_state_txt(sta->sae->state), sae_state_txt(state),
545                        MAC2STR(sta->addr), reason);
546           sta->sae->state = state;
547 }
548 
549 
sae_get_password(struct hostapd_data * hapd,struct sta_info * sta,const char * rx_id,struct sae_password_entry ** pw_entry,struct sae_pt ** s_pt,const struct sae_pk ** s_pk)550 const char * sae_get_password(struct hostapd_data *hapd,
551                                     struct sta_info *sta,
552                                     const char *rx_id,
553                                     struct sae_password_entry **pw_entry,
554                                     struct sae_pt **s_pt,
555                                     const struct sae_pk **s_pk)
556 {
557           const char *password = NULL;
558           struct sae_password_entry *pw;
559           struct sae_pt *pt = NULL;
560           const struct sae_pk *pk = NULL;
561           struct hostapd_sta_wpa_psk_short *psk = NULL;
562 
563           for (pw = hapd->conf->sae_passwords; pw; pw = pw->next) {
564                     if (!is_broadcast_ether_addr(pw->peer_addr) &&
565                         (!sta ||
566                          !ether_addr_equal(pw->peer_addr, sta->addr)))
567                               continue;
568                     if ((rx_id && !pw->identifier) || (!rx_id && pw->identifier))
569                               continue;
570                     if (rx_id && pw->identifier &&
571                         os_strcmp(rx_id, pw->identifier) != 0)
572                               continue;
573                     password = pw->password;
574                     pt = pw->pt;
575                     if (!(hapd->conf->mesh & MESH_ENABLED))
576                               pk = pw->pk;
577                     break;
578           }
579           if (!password) {
580                     password = hapd->conf->ssid.wpa_passphrase;
581                     pt = hapd->conf->ssid.pt;
582           }
583 
584           if (!password && sta) {
585                     for (psk = sta->psk; psk; psk = psk->next) {
586                               if (psk->is_passphrase) {
587                                         password = psk->passphrase;
588                                         break;
589                               }
590                     }
591           }
592 
593           if (pw_entry)
594                     *pw_entry = pw;
595           if (s_pt)
596                     *s_pt = pt;
597           if (s_pk)
598                     *s_pk = pk;
599 
600           return password;
601 }
602 
603 
auth_build_sae_commit(struct hostapd_data * hapd,struct sta_info * sta,int update,int status_code)604 static struct wpabuf * auth_build_sae_commit(struct hostapd_data *hapd,
605                                                        struct sta_info *sta, int update,
606                                                        int status_code)
607 {
608           struct wpabuf *buf;
609           const char *password = NULL;
610           struct sae_password_entry *pw;
611           const char *rx_id = NULL;
612           int use_pt = 0;
613           struct sae_pt *pt = NULL;
614           const struct sae_pk *pk = NULL;
615           const u8 *own_addr = hapd->own_addr;
616 
617 #ifdef CONFIG_IEEE80211BE
618           if (ap_sta_is_mld(hapd, sta))
619                     own_addr = hapd->mld->mld_addr;
620 #endif /* CONFIG_IEEE80211BE */
621 
622           if (sta->sae->tmp) {
623                     rx_id = sta->sae->tmp->pw_id;
624                     use_pt = sta->sae->h2e;
625 #ifdef CONFIG_SAE_PK
626                     os_memcpy(sta->sae->tmp->own_addr, own_addr, ETH_ALEN);
627                     os_memcpy(sta->sae->tmp->peer_addr, sta->addr, ETH_ALEN);
628 #endif /* CONFIG_SAE_PK */
629           }
630 
631           if (rx_id && hapd->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK)
632                     use_pt = 1;
633           else if (status_code == WLAN_STATUS_SUCCESS)
634                     use_pt = 0;
635           else if (status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
636                      status_code == WLAN_STATUS_SAE_PK)
637                     use_pt = 1;
638 
639           password = sae_get_password(hapd, sta, rx_id, &pw, &pt, &pk);
640           if (!password || (use_pt && !pt)) {
641                     wpa_printf(MSG_DEBUG, "SAE: No password available");
642                     return NULL;
643           }
644 
645           if (update && use_pt &&
646               sae_prepare_commit_pt(sta->sae, pt, own_addr, sta->addr,
647                                           NULL, pk) < 0)
648                     return NULL;
649 
650           if (update && !use_pt &&
651               sae_prepare_commit(own_addr, sta->addr,
652                                      (u8 *) password, os_strlen(password),
653                                      sta->sae) < 0) {
654                     wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE");
655                     return NULL;
656           }
657 
658           if (pw && pw->vlan_id) {
659                     if (!sta->sae->tmp) {
660                               wpa_printf(MSG_INFO,
661                                            "SAE: No temporary data allocated - cannot store VLAN ID");
662                               return NULL;
663                     }
664                     sta->sae->tmp->vlan_id = pw->vlan_id;
665           }
666 
667           buf = wpabuf_alloc(SAE_COMMIT_MAX_LEN +
668                                  (rx_id ? 3 + os_strlen(rx_id) : 0));
669           if (buf &&
670               sae_write_commit(sta->sae, buf, sta->sae->tmp ?
671                                    sta->sae->tmp->anti_clogging_token : NULL,
672                                    rx_id) < 0) {
673                     wpabuf_free(buf);
674                     buf = NULL;
675           }
676 
677           return buf;
678 }
679 
680 
auth_build_sae_confirm(struct hostapd_data * hapd,struct sta_info * sta)681 static struct wpabuf * auth_build_sae_confirm(struct hostapd_data *hapd,
682                                                         struct sta_info *sta)
683 {
684           struct wpabuf *buf;
685 
686           buf = wpabuf_alloc(SAE_CONFIRM_MAX_LEN);
687           if (buf == NULL)
688                     return NULL;
689 
690 #ifdef CONFIG_SAE_PK
691 #ifdef CONFIG_TESTING_OPTIONS
692           if (sta->sae->tmp)
693                     sta->sae->tmp->omit_pk_elem = hapd->conf->sae_pk_omit;
694 #endif /* CONFIG_TESTING_OPTIONS */
695 #endif /* CONFIG_SAE_PK */
696 
697           if (sae_write_confirm(sta->sae, buf) < 0) {
698                     wpabuf_free(buf);
699                     return NULL;
700           }
701 
702           return buf;
703 }
704 
705 
auth_sae_send_commit(struct hostapd_data * hapd,struct sta_info * sta,int update,int status_code)706 static int auth_sae_send_commit(struct hostapd_data *hapd,
707                                         struct sta_info *sta,
708                                         int update, int status_code)
709 {
710           struct wpabuf *data;
711           int reply_res;
712           u16 status;
713 
714           data = auth_build_sae_commit(hapd, sta, update, status_code);
715           if (!data && sta->sae->tmp && sta->sae->tmp->pw_id)
716                     return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER;
717           if (data == NULL)
718                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
719 
720           if (sta->sae->tmp && sta->sae->pk)
721                     status = WLAN_STATUS_SAE_PK;
722           else if (sta->sae->tmp && sta->sae->h2e)
723                     status = WLAN_STATUS_SAE_HASH_TO_ELEMENT;
724           else
725                     status = WLAN_STATUS_SUCCESS;
726 #ifdef CONFIG_TESTING_OPTIONS
727           if (hapd->conf->sae_commit_status >= 0 &&
728               hapd->conf->sae_commit_status != status) {
729                     wpa_printf(MSG_INFO,
730                                  "TESTING: Override SAE commit status code %u --> %d",
731                                  status, hapd->conf->sae_commit_status);
732                     status = hapd->conf->sae_commit_status;
733           }
734 #endif /* CONFIG_TESTING_OPTIONS */
735           reply_res = send_auth_reply(hapd, sta, sta->addr,
736                                             WLAN_AUTH_SAE, 1,
737                                             status, wpabuf_head(data),
738                                             wpabuf_len(data), "sae-send-commit");
739 
740           wpabuf_free(data);
741 
742           return reply_res;
743 }
744 
745 
auth_sae_send_confirm(struct hostapd_data * hapd,struct sta_info * sta)746 static int auth_sae_send_confirm(struct hostapd_data *hapd,
747                                          struct sta_info *sta)
748 {
749           struct wpabuf *data;
750           int reply_res;
751 
752           data = auth_build_sae_confirm(hapd, sta);
753           if (data == NULL)
754                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
755 
756           reply_res = send_auth_reply(hapd, sta, sta->addr,
757                                             WLAN_AUTH_SAE, 2,
758                                             WLAN_STATUS_SUCCESS, wpabuf_head(data),
759                                             wpabuf_len(data), "sae-send-confirm");
760 
761           wpabuf_free(data);
762 
763           return reply_res;
764 }
765 
766 #endif /* CONFIG_SAE */
767 
768 
769 #if defined(CONFIG_SAE) || defined(CONFIG_PASN)
770 
use_anti_clogging(struct hostapd_data * hapd)771 static int use_anti_clogging(struct hostapd_data *hapd)
772 {
773           struct sta_info *sta;
774           unsigned int open = 0;
775 
776           if (hapd->conf->anti_clogging_threshold == 0)
777                     return 1;
778 
779           for (sta = hapd->sta_list; sta; sta = sta->next) {
780 #ifdef CONFIG_SAE
781                     if (sta->sae &&
782                         (sta->sae->state == SAE_COMMITTED ||
783                          sta->sae->state == SAE_CONFIRMED))
784                               open++;
785 #endif /* CONFIG_SAE */
786 #ifdef CONFIG_PASN
787                     if (sta->pasn && sta->pasn->ecdh)
788                               open++;
789 #endif /* CONFIG_PASN */
790                     if (open >= hapd->conf->anti_clogging_threshold)
791                               return 1;
792           }
793 
794 #ifdef CONFIG_SAE
795           /* In addition to already existing open SAE sessions, check whether
796            * there are enough pending commit messages in the processing queue to
797            * potentially result in too many open sessions. */
798           if (open + dl_list_len(&hapd->sae_commit_queue) >=
799               hapd->conf->anti_clogging_threshold)
800                     return 1;
801 #endif /* CONFIG_SAE */
802 
803           return 0;
804 }
805 
806 #endif /* defined(CONFIG_SAE) || defined(CONFIG_PASN) */
807 
808 
809 #ifdef CONFIG_SAE
810 
sae_check_big_sync(struct hostapd_data * hapd,struct sta_info * sta)811 static int sae_check_big_sync(struct hostapd_data *hapd, struct sta_info *sta)
812 {
813           if (sta->sae->sync > hapd->conf->sae_sync) {
814                     sae_set_state(sta, SAE_NOTHING, "Sync > dot11RSNASAESync");
815                     sta->sae->sync = 0;
816                     if (sta->sae->tmp) {
817                               /* Disable this SAE instance for 10 seconds to avoid
818                                * unnecessary flood of multiple SAE commits in
819                                * unexpected mesh cases. */
820                               if (os_get_reltime(&sta->sae->tmp->disabled_until) == 0)
821                                         sta->sae->tmp->disabled_until.sec += 10;
822                     }
823                     return -1;
824           }
825           return 0;
826 }
827 
828 
sae_proto_instance_disabled(struct sta_info * sta)829 static bool sae_proto_instance_disabled(struct sta_info *sta)
830 {
831           struct sae_temporary_data *tmp;
832 
833           if (!sta->sae)
834                     return false;
835           tmp = sta->sae->tmp;
836           if (!tmp)
837                     return false;
838 
839           if (os_reltime_initialized(&tmp->disabled_until)) {
840                     struct os_reltime now;
841 
842                     os_get_reltime(&now);
843                     if (os_reltime_before(&now, &tmp->disabled_until))
844                               return true;
845           }
846 
847           return false;
848 }
849 
850 
auth_sae_retransmit_timer(void * eloop_ctx,void * eloop_data)851 static void auth_sae_retransmit_timer(void *eloop_ctx, void *eloop_data)
852 {
853           struct hostapd_data *hapd = eloop_ctx;
854           struct sta_info *sta = eloop_data;
855           int ret;
856 
857           if (sae_check_big_sync(hapd, sta))
858                     return;
859           sta->sae->sync++;
860           wpa_printf(MSG_DEBUG, "SAE: Auth SAE retransmit timer for " MACSTR
861                        " (sync=%d state=%s)",
862                        MAC2STR(sta->addr), sta->sae->sync,
863                        sae_state_txt(sta->sae->state));
864 
865           switch (sta->sae->state) {
866           case SAE_COMMITTED:
867                     ret = auth_sae_send_commit(hapd, sta, 0, -1);
868                     eloop_register_timeout(0,
869                                                hapd->dot11RSNASAERetransPeriod * 1000,
870                                                auth_sae_retransmit_timer, hapd, sta);
871                     break;
872           case SAE_CONFIRMED:
873                     ret = auth_sae_send_confirm(hapd, sta);
874                     eloop_register_timeout(0,
875                                                hapd->dot11RSNASAERetransPeriod * 1000,
876                                                auth_sae_retransmit_timer, hapd, sta);
877                     break;
878           default:
879                     ret = -1;
880                     break;
881           }
882 
883           if (ret != WLAN_STATUS_SUCCESS)
884                     wpa_printf(MSG_INFO, "SAE: Failed to retransmit: ret=%d", ret);
885 }
886 
887 
sae_clear_retransmit_timer(struct hostapd_data * hapd,struct sta_info * sta)888 void sae_clear_retransmit_timer(struct hostapd_data *hapd, struct sta_info *sta)
889 {
890           eloop_cancel_timeout(auth_sae_retransmit_timer, hapd, sta);
891 }
892 
893 
sae_set_retransmit_timer(struct hostapd_data * hapd,struct sta_info * sta)894 static void sae_set_retransmit_timer(struct hostapd_data *hapd,
895                                              struct sta_info *sta)
896 {
897           if (!(hapd->conf->mesh & MESH_ENABLED))
898                     return;
899 
900           eloop_cancel_timeout(auth_sae_retransmit_timer, hapd, sta);
901           eloop_register_timeout(0, hapd->dot11RSNASAERetransPeriod * 1000,
902                                      auth_sae_retransmit_timer, hapd, sta);
903 }
904 
905 
sae_sme_send_external_auth_status(struct hostapd_data * hapd,struct sta_info * sta,u16 status)906 static void sae_sme_send_external_auth_status(struct hostapd_data *hapd,
907                                                         struct sta_info *sta, u16 status)
908 {
909           struct external_auth params;
910 
911           os_memset(&params, 0, sizeof(params));
912           params.status = status;
913 
914 #ifdef CONFIG_IEEE80211BE
915           if (ap_sta_is_mld(hapd, sta))
916                     params.bssid =
917                               sta->mld_info.links[sta->mld_assoc_link_id].peer_addr;
918 #endif /* CONFIG_IEEE80211BE */
919           if (!params.bssid)
920                     params.bssid = sta->addr;
921 
922           if (status == WLAN_STATUS_SUCCESS && sta->sae &&
923               !hapd->conf->disable_pmksa_caching)
924                     params.pmkid = sta->sae->pmkid;
925 
926           hostapd_drv_send_external_auth_status(hapd, &params);
927 }
928 
929 
sae_accept_sta(struct hostapd_data * hapd,struct sta_info * sta)930 void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta)
931 {
932 #ifndef CONFIG_NO_VLAN
933           struct vlan_description vlan_desc;
934 
935           if (sta->sae->tmp && sta->sae->tmp->vlan_id > 0) {
936                     wpa_printf(MSG_DEBUG, "SAE: Assign STA " MACSTR
937                                  " to VLAN ID %d",
938                                  MAC2STR(sta->addr), sta->sae->tmp->vlan_id);
939 
940                     if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_VLAN_OFFLOAD)) {
941                               os_memset(&vlan_desc, 0, sizeof(vlan_desc));
942                               vlan_desc.notempty = 1;
943                               vlan_desc.untagged = sta->sae->tmp->vlan_id;
944                               if (!hostapd_vlan_valid(hapd->conf->vlan, &vlan_desc)) {
945                                         wpa_printf(MSG_INFO,
946                                                      "Invalid VLAN ID %d in sae_password",
947                                                      sta->sae->tmp->vlan_id);
948                                         return;
949                               }
950 
951                               if (ap_sta_set_vlan(hapd, sta, &vlan_desc) < 0 ||
952                                   ap_sta_bind_vlan(hapd, sta) < 0) {
953                                         wpa_printf(MSG_INFO,
954                                                      "Failed to assign VLAN ID %d from sae_password to "
955                                                      MACSTR, sta->sae->tmp->vlan_id,
956                                                      MAC2STR(sta->addr));
957                                         return;
958                               }
959                     } else {
960                               sta->vlan_id = sta->sae->tmp->vlan_id;
961                     }
962           }
963 #endif /* CONFIG_NO_VLAN */
964 
965           sta->flags |= WLAN_STA_AUTH;
966           sta->auth_alg = WLAN_AUTH_SAE;
967           mlme_authenticate_indication(hapd, sta);
968           wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
969           sae_set_state(sta, SAE_ACCEPTED, "Accept Confirm");
970           crypto_bignum_deinit(sta->sae->peer_commit_scalar_accepted, 0);
971           sta->sae->peer_commit_scalar_accepted = sta->sae->peer_commit_scalar;
972           sta->sae->peer_commit_scalar = NULL;
973           wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr,
974                                      sta->sae->pmk, sta->sae->pmk_len,
975                                      sta->sae->pmkid, sta->sae->akmp);
976           sae_sme_send_external_auth_status(hapd, sta, WLAN_STATUS_SUCCESS);
977 }
978 
979 
sae_sm_step(struct hostapd_data * hapd,struct sta_info * sta,u16 auth_transaction,u16 status_code,int allow_reuse,int * sta_removed)980 static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
981                            u16 auth_transaction, u16 status_code,
982                            int allow_reuse, int *sta_removed)
983 {
984           int ret;
985 
986           *sta_removed = 0;
987 
988           if (auth_transaction != 1 && auth_transaction != 2)
989                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
990 
991           wpa_printf(MSG_DEBUG, "SAE: Peer " MACSTR " state=%s auth_trans=%u",
992                        MAC2STR(sta->addr), sae_state_txt(sta->sae->state),
993                        auth_transaction);
994 
995           if (auth_transaction == 1 && sae_proto_instance_disabled(sta)) {
996                     wpa_printf(MSG_DEBUG,
997                                  "SAE: Protocol instance temporarily disabled - discard received SAE commit");
998                     return WLAN_STATUS_SUCCESS;
999           }
1000 
1001           switch (sta->sae->state) {
1002           case SAE_NOTHING:
1003                     if (auth_transaction == 1) {
1004                               if (sta->sae->tmp) {
1005                                         sta->sae->h2e =
1006                                                   (status_code ==
1007                                                    WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
1008                                                    status_code == WLAN_STATUS_SAE_PK);
1009                                         sta->sae->pk =
1010                                                   status_code == WLAN_STATUS_SAE_PK;
1011                               }
1012                               ret = auth_sae_send_commit(hapd, sta,
1013                                                                !allow_reuse, status_code);
1014                               if (ret)
1015                                         return ret;
1016                               sae_set_state(sta, SAE_COMMITTED, "Sent Commit");
1017 
1018                               if (sae_process_commit(sta->sae) < 0)
1019                                         return WLAN_STATUS_UNSPECIFIED_FAILURE;
1020 
1021                               /*
1022                                * In mesh case, both Commit and Confirm are sent
1023                                * immediately. In infrastructure BSS, by default, only
1024                                * a single Authentication frame (Commit) is expected
1025                                * from the AP here and the second one (Confirm) will
1026                                * be sent once the STA has sent its second
1027                                * Authentication frame (Confirm). This behavior can be
1028                                * overridden with explicit configuration so that the
1029                                * infrastructure BSS case sends both frames together.
1030                                */
1031                               if ((hapd->conf->mesh & MESH_ENABLED) ||
1032                                   hapd->conf->sae_confirm_immediate) {
1033                                         /*
1034                                          * Send both Commit and Confirm immediately
1035                                          * based on SAE finite state machine
1036                                          * Nothing -> Confirm transition.
1037                                          */
1038                                         ret = auth_sae_send_confirm(hapd, sta);
1039                                         if (ret)
1040                                                   return ret;
1041                                         sae_set_state(sta, SAE_CONFIRMED,
1042                                                         "Sent Confirm (mesh)");
1043                               } else {
1044                                         /*
1045                                          * For infrastructure BSS, send only the Commit
1046                                          * message now to get alternating sequence of
1047                                          * Authentication frames between the AP and STA.
1048                                          * Confirm will be sent in
1049                                          * Committed -> Confirmed/Accepted transition
1050                                          * when receiving Confirm from STA.
1051                                          */
1052                               }
1053                               sta->sae->sync = 0;
1054                               sae_set_retransmit_timer(hapd, sta);
1055                     } else {
1056                               hostapd_logger(hapd, sta->addr,
1057                                                HOSTAPD_MODULE_IEEE80211,
1058                                                HOSTAPD_LEVEL_DEBUG,
1059                                                "SAE confirm before commit");
1060                     }
1061                     break;
1062           case SAE_COMMITTED:
1063                     sae_clear_retransmit_timer(hapd, sta);
1064                     if (auth_transaction == 1) {
1065                               if (sae_process_commit(sta->sae) < 0)
1066                                         return WLAN_STATUS_UNSPECIFIED_FAILURE;
1067 
1068                               ret = auth_sae_send_confirm(hapd, sta);
1069                               if (ret)
1070                                         return ret;
1071                               sae_set_state(sta, SAE_CONFIRMED, "Sent Confirm");
1072                               sta->sae->sync = 0;
1073                               sae_set_retransmit_timer(hapd, sta);
1074                     } else if (hapd->conf->mesh & MESH_ENABLED) {
1075                               /*
1076                                * In mesh case, follow SAE finite state machine and
1077                                * send Commit now, if sync count allows.
1078                                */
1079                               if (sae_check_big_sync(hapd, sta))
1080                                         return WLAN_STATUS_SUCCESS;
1081                               sta->sae->sync++;
1082 
1083                               ret = auth_sae_send_commit(hapd, sta, 0, status_code);
1084                               if (ret)
1085                                         return ret;
1086 
1087                               sae_set_retransmit_timer(hapd, sta);
1088                     } else {
1089                               /*
1090                                * For instructure BSS, send the postponed Confirm from
1091                                * Nothing -> Confirmed transition that was reduced to
1092                                * Nothing -> Committed above.
1093                                */
1094                               ret = auth_sae_send_confirm(hapd, sta);
1095                               if (ret)
1096                                         return ret;
1097 
1098                               sae_set_state(sta, SAE_CONFIRMED, "Sent Confirm");
1099 
1100                               /*
1101                                * Since this was triggered on Confirm RX, run another
1102                                * step to get to Accepted without waiting for
1103                                * additional events.
1104                                */
1105                               return sae_sm_step(hapd, sta, auth_transaction,
1106                                                      WLAN_STATUS_SUCCESS, 0, sta_removed);
1107                     }
1108                     break;
1109           case SAE_CONFIRMED:
1110                     sae_clear_retransmit_timer(hapd, sta);
1111                     if (auth_transaction == 1) {
1112                               if (sae_check_big_sync(hapd, sta))
1113                                         return WLAN_STATUS_SUCCESS;
1114                               sta->sae->sync++;
1115 
1116                               ret = auth_sae_send_commit(hapd, sta, 1, status_code);
1117                               if (ret)
1118                                         return ret;
1119 
1120                               if (sae_process_commit(sta->sae) < 0)
1121                                         return WLAN_STATUS_UNSPECIFIED_FAILURE;
1122 
1123                               ret = auth_sae_send_confirm(hapd, sta);
1124                               if (ret)
1125                                         return ret;
1126 
1127                               sae_set_retransmit_timer(hapd, sta);
1128                     } else {
1129                               sta->sae->send_confirm = 0xffff;
1130                               sae_accept_sta(hapd, sta);
1131                     }
1132                     break;
1133           case SAE_ACCEPTED:
1134                     if (auth_transaction == 1 &&
1135                         (hapd->conf->mesh & MESH_ENABLED)) {
1136                               wpa_printf(MSG_DEBUG, "SAE: remove the STA (" MACSTR
1137                                            ") doing reauthentication",
1138                                            MAC2STR(sta->addr));
1139                               wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
1140                               ap_free_sta(hapd, sta);
1141                               *sta_removed = 1;
1142                     } else if (auth_transaction == 1) {
1143                               wpa_printf(MSG_DEBUG, "SAE: Start reauthentication");
1144                               ret = auth_sae_send_commit(hapd, sta, 1, status_code);
1145                               if (ret)
1146                                         return ret;
1147                               sae_set_state(sta, SAE_COMMITTED, "Sent Commit");
1148 
1149                               if (sae_process_commit(sta->sae) < 0)
1150                                         return WLAN_STATUS_UNSPECIFIED_FAILURE;
1151                               sta->sae->sync = 0;
1152                               sae_set_retransmit_timer(hapd, sta);
1153                     } else {
1154                               if (sae_check_big_sync(hapd, sta))
1155                                         return WLAN_STATUS_SUCCESS;
1156                               sta->sae->sync++;
1157 
1158                               ret = auth_sae_send_confirm(hapd, sta);
1159                               sae_clear_temp_data(sta->sae);
1160                               if (ret)
1161                                         return ret;
1162                     }
1163                     break;
1164           default:
1165                     wpa_printf(MSG_ERROR, "SAE: invalid state %d",
1166                                  sta->sae->state);
1167                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
1168           }
1169           return WLAN_STATUS_SUCCESS;
1170 }
1171 
1172 
sae_pick_next_group(struct hostapd_data * hapd,struct sta_info * sta)1173 static void sae_pick_next_group(struct hostapd_data *hapd, struct sta_info *sta)
1174 {
1175           struct sae_data *sae = sta->sae;
1176           int i, *groups = hapd->conf->sae_groups;
1177           int default_groups[] = { 19, 0 };
1178 
1179           if (sae->state != SAE_COMMITTED)
1180                     return;
1181 
1182           wpa_printf(MSG_DEBUG, "SAE: Previously selected group: %d", sae->group);
1183 
1184           if (!groups)
1185                     groups = default_groups;
1186           for (i = 0; groups[i] > 0; i++) {
1187                     if (sae->group == groups[i])
1188                               break;
1189           }
1190 
1191           if (groups[i] <= 0) {
1192                     wpa_printf(MSG_DEBUG,
1193                                  "SAE: Previously selected group not found from the current configuration");
1194                     return;
1195           }
1196 
1197           for (;;) {
1198                     i++;
1199                     if (groups[i] <= 0) {
1200                               wpa_printf(MSG_DEBUG,
1201                                            "SAE: No alternative group enabled");
1202                               return;
1203                     }
1204 
1205                     if (sae_set_group(sae, groups[i]) < 0)
1206                               continue;
1207 
1208                     break;
1209           }
1210           wpa_printf(MSG_DEBUG, "SAE: Selected new group: %d", groups[i]);
1211 }
1212 
1213 
sae_status_success(struct hostapd_data * hapd,u16 status_code)1214 static int sae_status_success(struct hostapd_data *hapd, u16 status_code)
1215 {
1216           enum sae_pwe sae_pwe = hapd->conf->sae_pwe;
1217           int id_in_use;
1218           bool sae_pk = false;
1219 
1220           id_in_use = hostapd_sae_pw_id_in_use(hapd->conf);
1221           if (id_in_use == 2 && sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK)
1222                     sae_pwe = SAE_PWE_HASH_TO_ELEMENT;
1223           else if (id_in_use == 1 && sae_pwe == SAE_PWE_HUNT_AND_PECK)
1224                     sae_pwe = SAE_PWE_BOTH;
1225 #ifdef CONFIG_SAE_PK
1226           sae_pk = hostapd_sae_pk_in_use(hapd->conf);
1227           if (sae_pwe == SAE_PWE_HUNT_AND_PECK && sae_pk)
1228                     sae_pwe = SAE_PWE_BOTH;
1229 #endif /* CONFIG_SAE_PK */
1230           if (sae_pwe == SAE_PWE_HUNT_AND_PECK &&
1231               (hapd->conf->wpa_key_mgmt &
1232                (WPA_KEY_MGMT_SAE_EXT_KEY | WPA_KEY_MGMT_FT_SAE_EXT_KEY)))
1233                     sae_pwe = SAE_PWE_BOTH;
1234 
1235           return ((sae_pwe == SAE_PWE_HUNT_AND_PECK ||
1236                      sae_pwe == SAE_PWE_FORCE_HUNT_AND_PECK) &&
1237                     status_code == WLAN_STATUS_SUCCESS) ||
1238                     (sae_pwe == SAE_PWE_HASH_TO_ELEMENT &&
1239                      (status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
1240                       (sae_pk && status_code == WLAN_STATUS_SAE_PK))) ||
1241                     (sae_pwe == SAE_PWE_BOTH &&
1242                      (status_code == WLAN_STATUS_SUCCESS ||
1243                       status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
1244                       (sae_pk && status_code == WLAN_STATUS_SAE_PK)));
1245 }
1246 
1247 
sae_is_group_enabled(struct hostapd_data * hapd,int group)1248 static int sae_is_group_enabled(struct hostapd_data *hapd, int group)
1249 {
1250           int *groups = hapd->conf->sae_groups;
1251           int default_groups[] = { 19, 0 };
1252           int i;
1253 
1254           if (!groups)
1255                     groups = default_groups;
1256 
1257           for (i = 0; groups[i] > 0; i++) {
1258                     if (groups[i] == group)
1259                               return 1;
1260           }
1261 
1262           return 0;
1263 }
1264 
1265 
check_sae_rejected_groups(struct hostapd_data * hapd,struct sae_data * sae)1266 static int check_sae_rejected_groups(struct hostapd_data *hapd,
1267                                              struct sae_data *sae)
1268 {
1269           const struct wpabuf *groups;
1270           size_t i, count, len;
1271           const u8 *pos;
1272 
1273           if (!sae->tmp)
1274                     return 0;
1275           groups = sae->tmp->peer_rejected_groups;
1276           if (!groups)
1277                     return 0;
1278 
1279           pos = wpabuf_head(groups);
1280           len = wpabuf_len(groups);
1281           if (len & 1) {
1282                     wpa_printf(MSG_DEBUG,
1283                                  "SAE: Invalid length of the Rejected Groups element payload: %zu",
1284                                  len);
1285                     return 1;
1286           }
1287 
1288           count = len / 2;
1289           for (i = 0; i < count; i++) {
1290                     int enabled;
1291                     u16 group;
1292 
1293                     group = WPA_GET_LE16(pos);
1294                     pos += 2;
1295                     enabled = sae_is_group_enabled(hapd, group);
1296                     wpa_printf(MSG_DEBUG, "SAE: Rejected group %u is %s",
1297                                  group, enabled ? "enabled" : "disabled");
1298                     if (enabled)
1299                               return 1;
1300           }
1301 
1302           return 0;
1303 }
1304 
1305 
handle_auth_sae(struct hostapd_data * hapd,struct sta_info * sta,const struct ieee80211_mgmt * mgmt,size_t len,u16 auth_transaction,u16 status_code)1306 static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
1307                                   const struct ieee80211_mgmt *mgmt, size_t len,
1308                                   u16 auth_transaction, u16 status_code)
1309 {
1310           int resp = WLAN_STATUS_SUCCESS;
1311           struct wpabuf *data = NULL;
1312           int *groups = hapd->conf->sae_groups;
1313           int default_groups[] = { 19, 0 };
1314           const u8 *pos, *end;
1315           int sta_removed = 0;
1316           bool success_status;
1317 
1318           if (!groups)
1319                     groups = default_groups;
1320 
1321 #ifdef CONFIG_TESTING_OPTIONS
1322           if (hapd->conf->sae_reflection_attack && auth_transaction == 1) {
1323                     wpa_printf(MSG_DEBUG, "SAE: TESTING - reflection attack");
1324                     pos = mgmt->u.auth.variable;
1325                     end = ((const u8 *) mgmt) + len;
1326                     resp = status_code;
1327                     send_auth_reply(hapd, sta, sta->addr,
1328                                         WLAN_AUTH_SAE,
1329                                         auth_transaction, resp, pos, end - pos,
1330                                         "auth-sae-reflection-attack");
1331                     goto remove_sta;
1332           }
1333 
1334           if (hapd->conf->sae_commit_override && auth_transaction == 1) {
1335                     wpa_printf(MSG_DEBUG, "SAE: TESTING - commit override");
1336                     send_auth_reply(hapd, sta, sta->addr,
1337                                         WLAN_AUTH_SAE,
1338                                         auth_transaction, resp,
1339                                         wpabuf_head(hapd->conf->sae_commit_override),
1340                                         wpabuf_len(hapd->conf->sae_commit_override),
1341                                         "sae-commit-override");
1342                     goto remove_sta;
1343           }
1344 #endif /* CONFIG_TESTING_OPTIONS */
1345           if (!sta->sae) {
1346                     if (auth_transaction != 1 ||
1347                         !sae_status_success(hapd, status_code)) {
1348                               wpa_printf(MSG_DEBUG, "SAE: Unexpected Status Code %u",
1349                                            status_code);
1350                               resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1351                               goto reply;
1352                     }
1353                     sta->sae = os_zalloc(sizeof(*sta->sae));
1354                     if (!sta->sae) {
1355                               resp = -1;
1356                               goto remove_sta;
1357                     }
1358                     sae_set_state(sta, SAE_NOTHING, "Init");
1359                     sta->sae->sync = 0;
1360           }
1361 
1362           if (sta->mesh_sae_pmksa_caching) {
1363                     wpa_printf(MSG_DEBUG,
1364                                  "SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication");
1365                     wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
1366                     sta->mesh_sae_pmksa_caching = 0;
1367           }
1368 
1369           if (auth_transaction == 1) {
1370                     const u8 *token = NULL;
1371                     size_t token_len = 0;
1372                     int allow_reuse = 0;
1373 
1374                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1375                                      HOSTAPD_LEVEL_DEBUG,
1376                                      "start SAE authentication (RX commit, status=%u (%s))",
1377                                      status_code, status2str(status_code));
1378 
1379                     if ((hapd->conf->mesh & MESH_ENABLED) &&
1380                         status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ &&
1381                         sta->sae->tmp) {
1382                               pos = mgmt->u.auth.variable;
1383                               end = ((const u8 *) mgmt) + len;
1384                               if (pos + sizeof(le16) > end) {
1385                                         wpa_printf(MSG_ERROR,
1386                                                      "SAE: Too short anti-clogging token request");
1387                                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1388                                         goto reply;
1389                               }
1390                               resp = sae_group_allowed(sta->sae, groups,
1391                                                              WPA_GET_LE16(pos));
1392                               if (resp != WLAN_STATUS_SUCCESS) {
1393                                         wpa_printf(MSG_ERROR,
1394                                                      "SAE: Invalid group in anti-clogging token request");
1395                                         goto reply;
1396                               }
1397                               pos += sizeof(le16);
1398 
1399                               wpabuf_free(sta->sae->tmp->anti_clogging_token);
1400                               sta->sae->tmp->anti_clogging_token =
1401                                         wpabuf_alloc_copy(pos, end - pos);
1402                               if (sta->sae->tmp->anti_clogging_token == NULL) {
1403                                         wpa_printf(MSG_ERROR,
1404                                                      "SAE: Failed to alloc for anti-clogging token");
1405                                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1406                                         goto remove_sta;
1407                               }
1408 
1409                               /*
1410                                * IEEE Std 802.11-2012, 11.3.8.6.4: If the Status code
1411                                * is 76, a new Commit Message shall be constructed
1412                                * with the Anti-Clogging Token from the received
1413                                * Authentication frame, and the commit-scalar and
1414                                * COMMIT-ELEMENT previously sent.
1415                                */
1416                               resp = auth_sae_send_commit(hapd, sta, 0, status_code);
1417                               if (resp != WLAN_STATUS_SUCCESS) {
1418                                         wpa_printf(MSG_ERROR,
1419                                                      "SAE: Failed to send commit message");
1420                                         goto remove_sta;
1421                               }
1422                               sae_set_state(sta, SAE_COMMITTED,
1423                                               "Sent Commit (anti-clogging token case in mesh)");
1424                               sta->sae->sync = 0;
1425                               sae_set_retransmit_timer(hapd, sta);
1426                               return;
1427                     }
1428 
1429                     if ((hapd->conf->mesh & MESH_ENABLED) &&
1430                         status_code ==
1431                         WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED &&
1432                         sta->sae->tmp) {
1433                               wpa_printf(MSG_DEBUG,
1434                                            "SAE: Peer did not accept our SAE group");
1435                               sae_pick_next_group(hapd, sta);
1436                               goto remove_sta;
1437                     }
1438 
1439                     if (!sae_status_success(hapd, status_code))
1440                               goto remove_sta;
1441 
1442                     if (sae_proto_instance_disabled(sta)) {
1443                               wpa_printf(MSG_DEBUG,
1444                                            "SAE: Protocol instance temporarily disabled - discard received SAE commit");
1445                               return;
1446                     }
1447 
1448                     if (!(hapd->conf->mesh & MESH_ENABLED) &&
1449                         sta->sae->state == SAE_COMMITTED) {
1450                               /* This is needed in the infrastructure BSS case to
1451                                * address a sequence where a STA entry may remain in
1452                                * hostapd across two attempts to do SAE authentication
1453                                * by the same STA. The second attempt may end up trying
1454                                * to use a different group and that would not be
1455                                * allowed if we remain in Committed state with the
1456                                * previously set parameters. */
1457                               pos = mgmt->u.auth.variable;
1458                               end = ((const u8 *) mgmt) + len;
1459                               if (end - pos >= (int) sizeof(le16) &&
1460                                   sae_group_allowed(sta->sae, groups,
1461                                                         WPA_GET_LE16(pos)) ==
1462                                   WLAN_STATUS_SUCCESS) {
1463                                         /* Do not waste resources deriving the same PWE
1464                                          * again since the same group is reused. */
1465                                         sae_set_state(sta, SAE_NOTHING,
1466                                                         "Allow previous PWE to be reused");
1467                                         allow_reuse = 1;
1468                               } else {
1469                                         sae_set_state(sta, SAE_NOTHING,
1470                                                         "Clear existing state to allow restart");
1471                                         sae_clear_data(sta->sae);
1472                               }
1473                     }
1474 
1475                     resp = sae_parse_commit(sta->sae, mgmt->u.auth.variable,
1476                                                   ((const u8 *) mgmt) + len -
1477                                                   mgmt->u.auth.variable, &token,
1478                                                   &token_len, groups, status_code ==
1479                                                   WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
1480                                                   status_code == WLAN_STATUS_SAE_PK,
1481                                                   NULL);
1482                     if (resp == SAE_SILENTLY_DISCARD) {
1483                               wpa_printf(MSG_DEBUG,
1484                                            "SAE: Drop commit message from " MACSTR " due to reflection attack",
1485                                            MAC2STR(sta->addr));
1486                               goto remove_sta;
1487                     }
1488 
1489                     if (resp == WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER) {
1490                               wpa_msg(hapd->msg_ctx, MSG_INFO,
1491                                         WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER
1492                                         MACSTR, MAC2STR(sta->addr));
1493                               sae_clear_retransmit_timer(hapd, sta);
1494                               sae_set_state(sta, SAE_NOTHING,
1495                                               "Unknown Password Identifier");
1496                               goto remove_sta;
1497                     }
1498 
1499                     if (token &&
1500                         check_comeback_token(hapd->comeback_key,
1501                                                    hapd->comeback_pending_idx, sta->addr,
1502                                                    token, token_len)
1503                         < 0) {
1504                               wpa_printf(MSG_DEBUG, "SAE: Drop commit message with "
1505                                            "incorrect token from " MACSTR,
1506                                            MAC2STR(sta->addr));
1507                               resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1508                               goto remove_sta;
1509                     }
1510 
1511                     if (resp != WLAN_STATUS_SUCCESS)
1512                               goto reply;
1513 
1514                     if (check_sae_rejected_groups(hapd, sta->sae)) {
1515                               resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1516                               goto reply;
1517                     }
1518 
1519                     if (!token && use_anti_clogging(hapd) && !allow_reuse) {
1520                               int h2e = 0;
1521 
1522                               wpa_printf(MSG_DEBUG,
1523                                            "SAE: Request anti-clogging token from "
1524                                            MACSTR, MAC2STR(sta->addr));
1525                               if (sta->sae->tmp)
1526                                         h2e = sta->sae->h2e;
1527                               if (status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
1528                                   status_code == WLAN_STATUS_SAE_PK)
1529                                         h2e = 1;
1530                               data = auth_build_token_req(
1531                                         &hapd->last_comeback_key_update,
1532                                         hapd->comeback_key,
1533                                         hapd->comeback_idx,
1534                                         hapd->comeback_pending_idx,
1535                                         sizeof(hapd->comeback_pending_idx),
1536                                         sta->sae->group,
1537                                         sta->addr, h2e);
1538                               resp = WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ;
1539                               if (hapd->conf->mesh & MESH_ENABLED)
1540                                         sae_set_state(sta, SAE_NOTHING,
1541                                                         "Request anti-clogging token case in mesh");
1542                               goto reply;
1543                     }
1544 
1545                     resp = sae_sm_step(hapd, sta, auth_transaction,
1546                                            status_code, allow_reuse, &sta_removed);
1547           } else if (auth_transaction == 2) {
1548                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1549                                      HOSTAPD_LEVEL_DEBUG,
1550                                      "SAE authentication (RX confirm, status=%u (%s))",
1551                                      status_code, status2str(status_code));
1552                     if (status_code != WLAN_STATUS_SUCCESS)
1553                               goto remove_sta;
1554                     if (sta->sae->state >= SAE_CONFIRMED ||
1555                         !(hapd->conf->mesh & MESH_ENABLED)) {
1556                               const u8 *var;
1557                               size_t var_len;
1558                               u16 peer_send_confirm;
1559 
1560                               var = mgmt->u.auth.variable;
1561                               var_len = ((u8 *) mgmt) + len - mgmt->u.auth.variable;
1562                               if (var_len < 2) {
1563                                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1564                                         goto reply;
1565                               }
1566 
1567                               peer_send_confirm = WPA_GET_LE16(var);
1568 
1569                               if (sta->sae->state == SAE_ACCEPTED &&
1570                                   (peer_send_confirm <= sta->sae->rc ||
1571                                    peer_send_confirm == 0xffff)) {
1572                                         wpa_printf(MSG_DEBUG,
1573                                                      "SAE: Silently ignore unexpected Confirm from peer "
1574                                                      MACSTR
1575                                                      " (peer-send-confirm=%u Rc=%u)",
1576                                                      MAC2STR(sta->addr),
1577                                                      peer_send_confirm, sta->sae->rc);
1578                                         return;
1579                               }
1580 
1581                               if (sae_check_confirm(sta->sae, var, var_len,
1582                                                         NULL) < 0) {
1583                                         resp = WLAN_STATUS_CHALLENGE_FAIL;
1584                                         goto reply;
1585                               }
1586                               sta->sae->rc = peer_send_confirm;
1587                     }
1588                     resp = sae_sm_step(hapd, sta, auth_transaction,
1589                                            status_code, 0, &sta_removed);
1590           } else {
1591                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1592                                      HOSTAPD_LEVEL_DEBUG,
1593                                      "unexpected SAE authentication transaction %u (status=%u (%s))",
1594                                      auth_transaction, status_code,
1595                                      status2str(status_code));
1596                     if (status_code != WLAN_STATUS_SUCCESS)
1597                               goto remove_sta;
1598                     resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1599           }
1600 
1601 reply:
1602           if (!sta_removed && resp != WLAN_STATUS_SUCCESS) {
1603                     pos = mgmt->u.auth.variable;
1604                     end = ((const u8 *) mgmt) + len;
1605 
1606                     /* Copy the Finite Cyclic Group field from the request if we
1607                      * rejected it as unsupported group. */
1608                     if (resp == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED &&
1609                         !data && end - pos >= 2)
1610                               data = wpabuf_alloc_copy(pos, 2);
1611 
1612                     sae_sme_send_external_auth_status(hapd, sta, resp);
1613                     send_auth_reply(hapd, sta, sta->addr,
1614                                         WLAN_AUTH_SAE,
1615                                         auth_transaction, resp,
1616                                         data ? wpabuf_head(data) : (u8 *) "",
1617                                         data ? wpabuf_len(data) : 0, "auth-sae");
1618                     if (sta->sae && sta->sae->tmp && sta->sae->tmp->pw_id &&
1619                         resp == WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER &&
1620                         auth_transaction == 1) {
1621                               wpa_printf(MSG_DEBUG,
1622                                            "SAE: Clear stored password identifier since this SAE commit was not accepted");
1623                               os_free(sta->sae->tmp->pw_id);
1624                               sta->sae->tmp->pw_id = NULL;
1625                     }
1626           }
1627 
1628 remove_sta:
1629           if (auth_transaction == 1)
1630                     success_status = sae_status_success(hapd, status_code);
1631           else
1632                     success_status = status_code == WLAN_STATUS_SUCCESS;
1633           if (!sta_removed && sta->added_unassoc &&
1634               (resp != WLAN_STATUS_SUCCESS || !success_status)) {
1635                     hostapd_drv_sta_remove(hapd, sta->addr);
1636                     sta->added_unassoc = 0;
1637           }
1638           wpabuf_free(data);
1639 }
1640 
1641 
1642 /**
1643  * auth_sae_init_committed - Send COMMIT and start SAE in committed state
1644  * @hapd: BSS data for the device initiating the authentication
1645  * @sta: the peer to which commit authentication frame is sent
1646  *
1647  * This function implements Init event handling (IEEE Std 802.11-2012,
1648  * 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
1649  * sta->sae structure should be initialized appropriately via a call to
1650  * sae_prepare_commit().
1651  */
auth_sae_init_committed(struct hostapd_data * hapd,struct sta_info * sta)1652 int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta)
1653 {
1654           int ret;
1655 
1656           if (!sta->sae || !sta->sae->tmp)
1657                     return -1;
1658 
1659           if (sta->sae->state != SAE_NOTHING)
1660                     return -1;
1661 
1662           ret = auth_sae_send_commit(hapd, sta, 0, -1);
1663           if (ret)
1664                     return -1;
1665 
1666           sae_set_state(sta, SAE_COMMITTED, "Init and sent commit");
1667           sta->sae->sync = 0;
1668           sae_set_retransmit_timer(hapd, sta);
1669 
1670           return 0;
1671 }
1672 
1673 
auth_sae_process_commit(void * eloop_ctx,void * user_ctx)1674 void auth_sae_process_commit(void *eloop_ctx, void *user_ctx)
1675 {
1676           struct hostapd_data *hapd = eloop_ctx;
1677           struct hostapd_sae_commit_queue *q;
1678           unsigned int queue_len;
1679 
1680           q = dl_list_first(&hapd->sae_commit_queue,
1681                                 struct hostapd_sae_commit_queue, list);
1682           if (!q)
1683                     return;
1684           wpa_printf(MSG_DEBUG,
1685                        "SAE: Process next available message from queue");
1686           dl_list_del(&q->list);
1687           handle_auth(hapd, (const struct ieee80211_mgmt *) q->msg, q->len,
1688                         q->rssi, 1);
1689           os_free(q);
1690 
1691           if (eloop_is_timeout_registered(auth_sae_process_commit, hapd, NULL))
1692                     return;
1693           queue_len = dl_list_len(&hapd->sae_commit_queue);
1694           eloop_register_timeout(0, queue_len * 10000, auth_sae_process_commit,
1695                                      hapd, NULL);
1696 }
1697 
1698 
auth_sae_queue(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len,int rssi)1699 static void auth_sae_queue(struct hostapd_data *hapd,
1700                                  const struct ieee80211_mgmt *mgmt, size_t len,
1701                                  int rssi)
1702 {
1703           struct hostapd_sae_commit_queue *q, *q2;
1704           unsigned int queue_len;
1705           const struct ieee80211_mgmt *mgmt2;
1706 
1707           queue_len = dl_list_len(&hapd->sae_commit_queue);
1708           if (queue_len >= 15) {
1709                     wpa_printf(MSG_DEBUG,
1710                                  "SAE: No more room in message queue - drop the new frame from "
1711                                  MACSTR, MAC2STR(mgmt->sa));
1712                     return;
1713           }
1714 
1715           wpa_printf(MSG_DEBUG, "SAE: Queue Authentication message from "
1716                        MACSTR " for processing (queue_len %u)", MAC2STR(mgmt->sa),
1717                        queue_len);
1718           q = os_zalloc(sizeof(*q) + len);
1719           if (!q)
1720                     return;
1721           q->rssi = rssi;
1722           q->len = len;
1723           os_memcpy(q->msg, mgmt, len);
1724 
1725           /* Check whether there is already a queued Authentication frame from the
1726            * same station with the same transaction number and if so, replace that
1727            * queue entry with the new one. This avoids issues with a peer that
1728            * sends multiple times (e.g., due to frequent SAE retries). There is no
1729            * point in us trying to process the old attempts after a new one has
1730            * obsoleted them. */
1731           dl_list_for_each(q2, &hapd->sae_commit_queue,
1732                                struct hostapd_sae_commit_queue, list) {
1733                     mgmt2 = (const struct ieee80211_mgmt *) q2->msg;
1734                     if (ether_addr_equal(mgmt->sa, mgmt2->sa) &&
1735                         mgmt->u.auth.auth_transaction ==
1736                         mgmt2->u.auth.auth_transaction) {
1737                               wpa_printf(MSG_DEBUG,
1738                                            "SAE: Replace queued message from same STA with same transaction number");
1739                               dl_list_add(&q2->list, &q->list);
1740                               dl_list_del(&q2->list);
1741                               os_free(q2);
1742                               goto queued;
1743                     }
1744           }
1745 
1746           /* No pending identical entry, so add to the end of the queue */
1747           dl_list_add_tail(&hapd->sae_commit_queue, &q->list);
1748 
1749 queued:
1750           if (eloop_is_timeout_registered(auth_sae_process_commit, hapd, NULL))
1751                     return;
1752           eloop_register_timeout(0, queue_len * 10000, auth_sae_process_commit,
1753                                      hapd, NULL);
1754 }
1755 
1756 
auth_sae_queued_addr(struct hostapd_data * hapd,const u8 * addr)1757 static int auth_sae_queued_addr(struct hostapd_data *hapd, const u8 *addr)
1758 {
1759           struct hostapd_sae_commit_queue *q;
1760           const struct ieee80211_mgmt *mgmt;
1761 
1762           dl_list_for_each(q, &hapd->sae_commit_queue,
1763                                struct hostapd_sae_commit_queue, list) {
1764                     mgmt = (const struct ieee80211_mgmt *) q->msg;
1765                     if (ether_addr_equal(addr, mgmt->sa))
1766                               return 1;
1767           }
1768 
1769           return 0;
1770 }
1771 
1772 #endif /* CONFIG_SAE */
1773 
1774 
wpa_res_to_status_code(enum wpa_validate_result res)1775 static u16 wpa_res_to_status_code(enum wpa_validate_result res)
1776 {
1777           switch (res) {
1778           case WPA_IE_OK:
1779                     return WLAN_STATUS_SUCCESS;
1780           case WPA_INVALID_IE:
1781                     return WLAN_STATUS_INVALID_IE;
1782           case WPA_INVALID_GROUP:
1783                     return WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
1784           case WPA_INVALID_PAIRWISE:
1785                     return WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1786           case WPA_INVALID_AKMP:
1787                     return WLAN_STATUS_AKMP_NOT_VALID;
1788           case WPA_NOT_ENABLED:
1789                     return WLAN_STATUS_INVALID_IE;
1790           case WPA_ALLOC_FAIL:
1791                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
1792           case WPA_MGMT_FRAME_PROTECTION_VIOLATION:
1793                     return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
1794           case WPA_INVALID_MGMT_GROUP_CIPHER:
1795                     return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
1796           case WPA_INVALID_MDIE:
1797                     return WLAN_STATUS_INVALID_MDIE;
1798           case WPA_INVALID_PROTO:
1799                     return WLAN_STATUS_INVALID_IE;
1800           case WPA_INVALID_PMKID:
1801                     return WLAN_STATUS_INVALID_PMKID;
1802           case WPA_DENIED_OTHER_REASON:
1803                     return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
1804           }
1805           return WLAN_STATUS_INVALID_IE;
1806 }
1807 
1808 
1809 #ifdef CONFIG_FILS
1810 
1811 static void handle_auth_fils_finish(struct hostapd_data *hapd,
1812                                             struct sta_info *sta, u16 resp,
1813                                             struct wpabuf *data, int pub);
1814 
handle_auth_fils(struct hostapd_data * hapd,struct sta_info * sta,const u8 * pos,size_t len,u16 auth_alg,u16 auth_transaction,u16 status_code,void (* cb)(struct hostapd_data * hapd,struct sta_info * sta,u16 resp,struct wpabuf * data,int pub))1815 void handle_auth_fils(struct hostapd_data *hapd, struct sta_info *sta,
1816                           const u8 *pos, size_t len, u16 auth_alg,
1817                           u16 auth_transaction, u16 status_code,
1818                           void (*cb)(struct hostapd_data *hapd,
1819                                          struct sta_info *sta, u16 resp,
1820                                          struct wpabuf *data, int pub))
1821 {
1822           u16 resp = WLAN_STATUS_SUCCESS;
1823           const u8 *end;
1824           struct ieee802_11_elems elems;
1825           enum wpa_validate_result res;
1826           struct wpa_ie_data rsn;
1827           struct rsn_pmksa_cache_entry *pmksa = NULL;
1828 
1829           if (auth_transaction != 1 || status_code != WLAN_STATUS_SUCCESS)
1830                     return;
1831 
1832           end = pos + len;
1833 
1834           wpa_hexdump(MSG_DEBUG, "FILS: Authentication frame fields",
1835                         pos, end - pos);
1836 
1837           /* TODO: FILS PK */
1838 #ifdef CONFIG_FILS_SK_PFS
1839           if (auth_alg == WLAN_AUTH_FILS_SK_PFS) {
1840                     u16 group;
1841                     struct wpabuf *pub;
1842                     size_t elem_len;
1843 
1844                     /* Using FILS PFS */
1845 
1846                     /* Finite Cyclic Group */
1847                     if (end - pos < 2) {
1848                               wpa_printf(MSG_DEBUG,
1849                                            "FILS: No room for Finite Cyclic Group");
1850                               resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1851                               goto fail;
1852                     }
1853                     group = WPA_GET_LE16(pos);
1854                     pos += 2;
1855                     if (group != hapd->conf->fils_dh_group) {
1856                               wpa_printf(MSG_DEBUG,
1857                                            "FILS: Unsupported Finite Cyclic Group: %u (expected %u)",
1858                                            group, hapd->conf->fils_dh_group);
1859                               resp = WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
1860                               goto fail;
1861                     }
1862 
1863                     crypto_ecdh_deinit(sta->fils_ecdh);
1864                     sta->fils_ecdh = crypto_ecdh_init(group);
1865                     if (!sta->fils_ecdh) {
1866                               wpa_printf(MSG_INFO,
1867                                            "FILS: Could not initialize ECDH with group %d",
1868                                            group);
1869                               resp = WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
1870                               goto fail;
1871                     }
1872 
1873                     pub = crypto_ecdh_get_pubkey(sta->fils_ecdh, 1);
1874                     if (!pub) {
1875                               wpa_printf(MSG_DEBUG,
1876                                            "FILS: Failed to derive ECDH public key");
1877                               resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1878                               goto fail;
1879                     }
1880                     elem_len = wpabuf_len(pub);
1881                     wpabuf_free(pub);
1882 
1883                     /* Element */
1884                     if ((size_t) (end - pos) < elem_len) {
1885                               wpa_printf(MSG_DEBUG, "FILS: No room for Element");
1886                               resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1887                               goto fail;
1888                     }
1889 
1890                     wpabuf_free(sta->fils_g_sta);
1891                     sta->fils_g_sta = wpabuf_alloc_copy(pos, elem_len);
1892                     wpabuf_clear_free(sta->fils_dh_ss);
1893                     sta->fils_dh_ss = crypto_ecdh_set_peerkey(sta->fils_ecdh, 1,
1894                                                                         pos, elem_len);
1895                     if (!sta->fils_dh_ss) {
1896                               wpa_printf(MSG_DEBUG, "FILS: ECDH operation failed");
1897                               resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1898                               goto fail;
1899                     }
1900                     wpa_hexdump_buf_key(MSG_DEBUG, "FILS: DH_SS", sta->fils_dh_ss);
1901                     pos += elem_len;
1902           } else {
1903                     crypto_ecdh_deinit(sta->fils_ecdh);
1904                     sta->fils_ecdh = NULL;
1905                     wpabuf_clear_free(sta->fils_dh_ss);
1906                     sta->fils_dh_ss = NULL;
1907           }
1908 #endif /* CONFIG_FILS_SK_PFS */
1909 
1910           wpa_hexdump(MSG_DEBUG, "FILS: Remaining IEs", pos, end - pos);
1911           if (ieee802_11_parse_elems(pos, end - pos, &elems, 1) == ParseFailed) {
1912                     wpa_printf(MSG_DEBUG, "FILS: Could not parse elements");
1913                     resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1914                     goto fail;
1915           }
1916 
1917           /* RSNE */
1918           wpa_hexdump(MSG_DEBUG, "FILS: RSN element",
1919                         elems.rsn_ie, elems.rsn_ie_len);
1920           if (!elems.rsn_ie ||
1921               wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
1922                                          &rsn) < 0) {
1923                     wpa_printf(MSG_DEBUG, "FILS: No valid RSN element");
1924                     resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1925                     goto fail;
1926           }
1927 
1928           if (!sta->wpa_sm)
1929                     sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr,
1930                                                             NULL);
1931           if (!sta->wpa_sm) {
1932                     wpa_printf(MSG_DEBUG,
1933                                  "FILS: Failed to initialize RSN state machine");
1934                     resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1935                     goto fail;
1936           }
1937 
1938           res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
1939                                           hapd->iface->freq,
1940                                           elems.rsn_ie - 2, elems.rsn_ie_len + 2,
1941                                           elems.rsnxe ? elems.rsnxe - 2 : NULL,
1942                                           elems.rsnxe ? elems.rsnxe_len + 2 : 0,
1943                                           elems.mdie, elems.mdie_len, NULL, 0, NULL);
1944           resp = wpa_res_to_status_code(res);
1945           if (resp != WLAN_STATUS_SUCCESS)
1946                     goto fail;
1947 
1948           if (!elems.fils_nonce) {
1949                     wpa_printf(MSG_DEBUG, "FILS: No FILS Nonce field");
1950                     resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1951                     goto fail;
1952           }
1953           wpa_hexdump(MSG_DEBUG, "FILS: SNonce", elems.fils_nonce,
1954                         FILS_NONCE_LEN);
1955           os_memcpy(sta->fils_snonce, elems.fils_nonce, FILS_NONCE_LEN);
1956 
1957           /* PMKID List */
1958           if (rsn.pmkid && rsn.num_pmkid > 0) {
1959                     u8 num;
1960                     const u8 *pmkid;
1961 
1962                     wpa_hexdump(MSG_DEBUG, "FILS: PMKID List",
1963                                   rsn.pmkid, rsn.num_pmkid * PMKID_LEN);
1964 
1965                     pmkid = rsn.pmkid;
1966                     num = rsn.num_pmkid;
1967                     while (num) {
1968                               wpa_hexdump(MSG_DEBUG, "FILS: PMKID", pmkid, PMKID_LEN);
1969                               pmksa = wpa_auth_pmksa_get(hapd->wpa_auth, sta->addr,
1970                                                                pmkid);
1971                               if (pmksa)
1972                                         break;
1973                               pmksa = wpa_auth_pmksa_get_fils_cache_id(hapd->wpa_auth,
1974                                                                                  sta->addr,
1975                                                                                  pmkid);
1976                               if (pmksa)
1977                                         break;
1978                               pmkid += PMKID_LEN;
1979                               num--;
1980                     }
1981           }
1982           if (pmksa && wpa_auth_sta_key_mgmt(sta->wpa_sm) != pmksa->akmp) {
1983                     wpa_printf(MSG_DEBUG,
1984                                  "FILS: Matching PMKSA cache entry has different AKMP (0x%x != 0x%x) - ignore",
1985                                  wpa_auth_sta_key_mgmt(sta->wpa_sm), pmksa->akmp);
1986                     pmksa = NULL;
1987           }
1988           if (pmksa)
1989                     wpa_printf(MSG_DEBUG, "FILS: Found matching PMKSA cache entry");
1990 
1991           /* FILS Session */
1992           if (!elems.fils_session) {
1993                     wpa_printf(MSG_DEBUG, "FILS: No FILS Session element");
1994                     resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1995                     goto fail;
1996           }
1997           wpa_hexdump(MSG_DEBUG, "FILS: FILS Session", elems.fils_session,
1998                         FILS_SESSION_LEN);
1999           os_memcpy(sta->fils_session, elems.fils_session, FILS_SESSION_LEN);
2000 
2001           /* Wrapped Data */
2002           if (elems.wrapped_data) {
2003                     wpa_hexdump(MSG_DEBUG, "FILS: Wrapped Data",
2004                                   elems.wrapped_data,
2005                                   elems.wrapped_data_len);
2006                     if (!pmksa) {
2007 #ifndef CONFIG_NO_RADIUS
2008                               if (!sta->eapol_sm) {
2009                                         sta->eapol_sm =
2010                                                   ieee802_1x_alloc_eapol_sm(hapd, sta);
2011                               }
2012                               wpa_printf(MSG_DEBUG,
2013                                            "FILS: Forward EAP-Initiate/Re-auth to authentication server");
2014                               ieee802_1x_encapsulate_radius(
2015                                         hapd, sta, elems.wrapped_data,
2016                                         elems.wrapped_data_len);
2017                               sta->fils_pending_cb = cb;
2018                               wpa_printf(MSG_DEBUG,
2019                                            "FILS: Will send Authentication frame once the response from authentication server is available");
2020                               sta->flags |= WLAN_STA_PENDING_FILS_ERP;
2021                               /* Calculate pending PMKID here so that we do not need
2022                                * to maintain a copy of the EAP-Initiate/Reauth
2023                                * message. */
2024                               if (fils_pmkid_erp(wpa_auth_sta_key_mgmt(sta->wpa_sm),
2025                                                      elems.wrapped_data,
2026                                                      elems.wrapped_data_len,
2027                                                      sta->fils_erp_pmkid) == 0)
2028                                         sta->fils_erp_pmkid_set = 1;
2029                               return;
2030 #else /* CONFIG_NO_RADIUS */
2031                               resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2032                               goto fail;
2033 #endif /* CONFIG_NO_RADIUS */
2034                     }
2035           }
2036 
2037 fail:
2038           if (cb) {
2039                     struct wpabuf *data;
2040                     int pub = 0;
2041 
2042                     data = prepare_auth_resp_fils(hapd, sta, &resp, pmksa, NULL,
2043                                                         NULL, 0, &pub);
2044                     if (!data) {
2045                               wpa_printf(MSG_DEBUG,
2046                                            "%s: prepare_auth_resp_fils() returned failure",
2047                                            __func__);
2048                     }
2049 
2050                     cb(hapd, sta, resp, data, pub);
2051           }
2052 }
2053 
2054 
2055 static struct wpabuf *
prepare_auth_resp_fils(struct hostapd_data * hapd,struct sta_info * sta,u16 * resp,struct rsn_pmksa_cache_entry * pmksa,struct wpabuf * erp_resp,const u8 * msk,size_t msk_len,int * is_pub)2056 prepare_auth_resp_fils(struct hostapd_data *hapd,
2057                            struct sta_info *sta, u16 *resp,
2058                            struct rsn_pmksa_cache_entry *pmksa,
2059                            struct wpabuf *erp_resp,
2060                            const u8 *msk, size_t msk_len,
2061                            int *is_pub)
2062 {
2063           u8 fils_nonce[FILS_NONCE_LEN];
2064           size_t ielen;
2065           struct wpabuf *data = NULL;
2066           const u8 *ie;
2067           u8 *ie_buf = NULL;
2068           const u8 *pmk = NULL;
2069           size_t pmk_len = 0;
2070           u8 pmk_buf[PMK_LEN_MAX];
2071           struct wpabuf *pub = NULL;
2072 
2073           if (*resp != WLAN_STATUS_SUCCESS)
2074                     goto fail;
2075 
2076           ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ielen);
2077           if (!ie) {
2078                     *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2079                     goto fail;
2080           }
2081 
2082           if (pmksa) {
2083                     /* Add PMKID of the selected PMKSA into RSNE */
2084                     ie_buf = os_malloc(ielen + 2 + 2 + PMKID_LEN);
2085                     if (!ie_buf) {
2086                               *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2087                               goto fail;
2088                     }
2089 
2090                     os_memcpy(ie_buf, ie, ielen);
2091                     if (wpa_insert_pmkid(ie_buf, &ielen, pmksa->pmkid, true) < 0) {
2092                               *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2093                               goto fail;
2094                     }
2095                     ie = ie_buf;
2096           }
2097 
2098           if (random_get_bytes(fils_nonce, FILS_NONCE_LEN) < 0) {
2099                     *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2100                     goto fail;
2101           }
2102           wpa_hexdump(MSG_DEBUG, "RSN: Generated FILS Nonce",
2103                         fils_nonce, FILS_NONCE_LEN);
2104 
2105 #ifdef CONFIG_FILS_SK_PFS
2106           if (sta->fils_dh_ss && sta->fils_ecdh) {
2107                     pub = crypto_ecdh_get_pubkey(sta->fils_ecdh, 1);
2108                     if (!pub) {
2109                               *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2110                               goto fail;
2111                     }
2112           }
2113 #endif /* CONFIG_FILS_SK_PFS */
2114 
2115           data = wpabuf_alloc(1000 + ielen + (pub ? wpabuf_len(pub) : 0));
2116           if (!data) {
2117                     *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2118                     goto fail;
2119           }
2120 
2121           /* TODO: FILS PK */
2122 #ifdef CONFIG_FILS_SK_PFS
2123           if (pub) {
2124                     /* Finite Cyclic Group */
2125                     wpabuf_put_le16(data, hapd->conf->fils_dh_group);
2126 
2127                     /* Element */
2128                     wpabuf_put_buf(data, pub);
2129           }
2130 #endif /* CONFIG_FILS_SK_PFS */
2131 
2132           /* RSNE */
2133           wpabuf_put_data(data, ie, ielen);
2134 
2135           /* MDE when using FILS+FT (already included in ie,ielen with RSNE) */
2136 
2137 #ifdef CONFIG_IEEE80211R_AP
2138           if (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta->wpa_sm))) {
2139                     /* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */
2140                     int res;
2141 
2142                     res = wpa_auth_write_fte(hapd->wpa_auth, sta->wpa_sm,
2143                                                    wpabuf_put(data, 0),
2144                                                    wpabuf_tailroom(data));
2145                     if (res < 0) {
2146                               *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2147                               goto fail;
2148                     }
2149                     wpabuf_put(data, res);
2150           }
2151 #endif /* CONFIG_IEEE80211R_AP */
2152 
2153           /* FILS Nonce */
2154           wpabuf_put_u8(data, WLAN_EID_EXTENSION); /* Element ID */
2155           wpabuf_put_u8(data, 1 + FILS_NONCE_LEN); /* Length */
2156           /* Element ID Extension */
2157           wpabuf_put_u8(data, WLAN_EID_EXT_FILS_NONCE);
2158           wpabuf_put_data(data, fils_nonce, FILS_NONCE_LEN);
2159 
2160           /* FILS Session */
2161           wpabuf_put_u8(data, WLAN_EID_EXTENSION); /* Element ID */
2162           wpabuf_put_u8(data, 1 + FILS_SESSION_LEN); /* Length */
2163           /* Element ID Extension */
2164           wpabuf_put_u8(data, WLAN_EID_EXT_FILS_SESSION);
2165           wpabuf_put_data(data, sta->fils_session, FILS_SESSION_LEN);
2166 
2167           /* Wrapped Data */
2168           if (!pmksa && erp_resp) {
2169                     wpabuf_put_u8(data, WLAN_EID_EXTENSION); /* Element ID */
2170                     wpabuf_put_u8(data, 1 + wpabuf_len(erp_resp)); /* Length */
2171                     /* Element ID Extension */
2172                     wpabuf_put_u8(data, WLAN_EID_EXT_WRAPPED_DATA);
2173                     wpabuf_put_buf(data, erp_resp);
2174 
2175                     if (fils_rmsk_to_pmk(wpa_auth_sta_key_mgmt(sta->wpa_sm),
2176                                              msk, msk_len, sta->fils_snonce, fils_nonce,
2177                                              sta->fils_dh_ss ?
2178                                              wpabuf_head(sta->fils_dh_ss) : NULL,
2179                                              sta->fils_dh_ss ?
2180                                              wpabuf_len(sta->fils_dh_ss) : 0,
2181                                              pmk_buf, &pmk_len)) {
2182                               wpa_printf(MSG_DEBUG, "FILS: Failed to derive PMK");
2183                               *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2184                               wpabuf_free(data);
2185                               data = NULL;
2186                               goto fail;
2187                     }
2188                     pmk = pmk_buf;
2189 
2190                     /* Don't use DHss in PTK derivation if PMKSA caching is not
2191                      * used. */
2192                     wpabuf_clear_free(sta->fils_dh_ss);
2193                     sta->fils_dh_ss = NULL;
2194 
2195                     if (sta->fils_erp_pmkid_set) {
2196                               /* TODO: get PMKLifetime from WPA parameters */
2197                               unsigned int dot11RSNAConfigPMKLifetime = 43200;
2198                               int session_timeout;
2199 
2200                               session_timeout = dot11RSNAConfigPMKLifetime;
2201                               if (sta->session_timeout_set) {
2202                                         struct os_reltime now, diff;
2203 
2204                                         os_get_reltime(&now);
2205                                         os_reltime_sub(&sta->session_timeout, &now,
2206                                                          &diff);
2207                                         session_timeout = diff.sec;
2208                               }
2209 
2210                               sta->fils_erp_pmkid_set = 0;
2211                               wpa_auth_add_fils_pmk_pmkid(sta->wpa_sm, pmk, pmk_len,
2212                                                                 sta->fils_erp_pmkid);
2213                               if (!hapd->conf->disable_pmksa_caching &&
2214                                   wpa_auth_pmksa_add2(
2215                                             hapd->wpa_auth, sta->addr,
2216                                             pmk, pmk_len,
2217                                             sta->fils_erp_pmkid,
2218                                             session_timeout,
2219                                             wpa_auth_sta_key_mgmt(sta->wpa_sm),
2220                                             NULL) < 0) {
2221                                         wpa_printf(MSG_ERROR,
2222                                                      "FILS: Failed to add PMKSA cache entry based on ERP");
2223                               }
2224                     }
2225           } else if (pmksa) {
2226                     pmk = pmksa->pmk;
2227                     pmk_len = pmksa->pmk_len;
2228           }
2229 
2230           if (!pmk) {
2231                     wpa_printf(MSG_DEBUG, "FILS: No PMK available");
2232                     *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2233                     wpabuf_free(data);
2234                     data = NULL;
2235                     goto fail;
2236           }
2237 
2238           if (fils_auth_pmk_to_ptk(sta->wpa_sm, pmk, pmk_len,
2239                                          sta->fils_snonce, fils_nonce,
2240                                          sta->fils_dh_ss ?
2241                                          wpabuf_head(sta->fils_dh_ss) : NULL,
2242                                          sta->fils_dh_ss ?
2243                                          wpabuf_len(sta->fils_dh_ss) : 0,
2244                                          sta->fils_g_sta, pub) < 0) {
2245                     *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2246                     wpabuf_free(data);
2247                     data = NULL;
2248                     goto fail;
2249           }
2250 
2251 fail:
2252           if (is_pub)
2253                     *is_pub = pub != NULL;
2254           os_free(ie_buf);
2255           wpabuf_free(pub);
2256           wpabuf_clear_free(sta->fils_dh_ss);
2257           sta->fils_dh_ss = NULL;
2258 #ifdef CONFIG_FILS_SK_PFS
2259           crypto_ecdh_deinit(sta->fils_ecdh);
2260           sta->fils_ecdh = NULL;
2261 #endif /* CONFIG_FILS_SK_PFS */
2262           return data;
2263 }
2264 
2265 
handle_auth_fils_finish(struct hostapd_data * hapd,struct sta_info * sta,u16 resp,struct wpabuf * data,int pub)2266 static void handle_auth_fils_finish(struct hostapd_data *hapd,
2267                                             struct sta_info *sta, u16 resp,
2268                                             struct wpabuf *data, int pub)
2269 {
2270           u16 auth_alg;
2271 
2272           auth_alg = (pub ||
2273                         resp == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED) ?
2274                     WLAN_AUTH_FILS_SK_PFS : WLAN_AUTH_FILS_SK;
2275           send_auth_reply(hapd, sta, sta->addr, auth_alg, 2, resp,
2276                               data ? wpabuf_head(data) : (u8 *) "",
2277                               data ? wpabuf_len(data) : 0, "auth-fils-finish");
2278           wpabuf_free(data);
2279 
2280           if (resp == WLAN_STATUS_SUCCESS) {
2281                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
2282                                      HOSTAPD_LEVEL_DEBUG,
2283                                      "authentication OK (FILS)");
2284                     sta->flags |= WLAN_STA_AUTH;
2285                     wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
2286                     sta->auth_alg = pub ? WLAN_AUTH_FILS_SK_PFS : WLAN_AUTH_FILS_SK;
2287                     mlme_authenticate_indication(hapd, sta);
2288           }
2289 }
2290 
2291 
ieee802_11_finish_fils_auth(struct hostapd_data * hapd,struct sta_info * sta,int success,struct wpabuf * erp_resp,const u8 * msk,size_t msk_len)2292 void ieee802_11_finish_fils_auth(struct hostapd_data *hapd,
2293                                          struct sta_info *sta, int success,
2294                                          struct wpabuf *erp_resp,
2295                                          const u8 *msk, size_t msk_len)
2296 {
2297           u16 resp;
2298           u32 flags = sta->flags;
2299 
2300           sta->flags &= ~(WLAN_STA_PENDING_FILS_ERP |
2301                               WLAN_STA_PENDING_PASN_FILS_ERP);
2302 
2303           resp = success ? WLAN_STATUS_SUCCESS : WLAN_STATUS_UNSPECIFIED_FAILURE;
2304 
2305           if (flags & WLAN_STA_PENDING_FILS_ERP) {
2306                     struct wpabuf *data;
2307                     int pub = 0;
2308 
2309                     if (!sta->fils_pending_cb)
2310                               return;
2311 
2312                     data = prepare_auth_resp_fils(hapd, sta, &resp, NULL, erp_resp,
2313                                                         msk, msk_len, &pub);
2314                     if (!data) {
2315                               wpa_printf(MSG_DEBUG,
2316                                            "%s: prepare_auth_resp_fils() failure",
2317                                            __func__);
2318                     }
2319                     sta->fils_pending_cb(hapd, sta, resp, data, pub);
2320 #ifdef CONFIG_PASN
2321           } else if (flags & WLAN_STA_PENDING_PASN_FILS_ERP) {
2322                     pasn_fils_auth_resp(hapd, sta, resp, erp_resp,
2323                                             msk, msk_len);
2324 #endif /* CONFIG_PASN */
2325           }
2326 }
2327 
2328 #endif /* CONFIG_FILS */
2329 
2330 
ieee802_11_allowed_address(struct hostapd_data * hapd,const u8 * addr,const u8 * msg,size_t len,struct radius_sta * info)2331 static int ieee802_11_allowed_address(struct hostapd_data *hapd, const u8 *addr,
2332                                               const u8 *msg, size_t len,
2333                                               struct radius_sta *info)
2334 {
2335           int res;
2336 
2337           res = hostapd_allowed_address(hapd, addr, msg, len, info, 0);
2338 
2339           if (res == HOSTAPD_ACL_REJECT) {
2340                     wpa_printf(MSG_DEBUG, "Station " MACSTR
2341                                  " not allowed to authenticate",
2342                                  MAC2STR(addr));
2343                     return HOSTAPD_ACL_REJECT;
2344           }
2345 
2346           if (res == HOSTAPD_ACL_PENDING) {
2347                     wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR
2348                                  " waiting for an external authentication",
2349                                  MAC2STR(addr));
2350                     /* Authentication code will re-send the authentication frame
2351                      * after it has received (and cached) information from the
2352                      * external source. */
2353                     return HOSTAPD_ACL_PENDING;
2354           }
2355 
2356           return res;
2357 }
2358 
2359 
ieee802_11_set_radius_info(struct hostapd_data * hapd,struct sta_info * sta,int res,struct radius_sta * info)2360 int ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
2361                                      int res, struct radius_sta *info)
2362 {
2363           u32 session_timeout = info->session_timeout;
2364           u32 acct_interim_interval = info->acct_interim_interval;
2365           struct vlan_description *vlan_id = &info->vlan_id;
2366           struct hostapd_sta_wpa_psk_short *psk = info->psk;
2367           char *identity = info->identity;
2368           char *radius_cui = info->radius_cui;
2369 
2370           if (vlan_id->notempty &&
2371               !hostapd_vlan_valid(hapd->conf->vlan, vlan_id)) {
2372                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
2373                                      HOSTAPD_LEVEL_INFO,
2374                                      "Invalid VLAN %d%s received from RADIUS server",
2375                                      vlan_id->untagged,
2376                                      vlan_id->tagged[0] ? "+" : "");
2377                     return -1;
2378           }
2379           if (ap_sta_set_vlan(hapd, sta, vlan_id) < 0)
2380                     return -1;
2381           if (sta->vlan_id)
2382                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
2383                                      HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
2384 
2385           hostapd_free_psk_list(sta->psk);
2386           if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED)
2387                     hostapd_copy_psk_list(&sta->psk, psk);
2388           else
2389                     sta->psk = NULL;
2390 
2391           os_free(sta->identity);
2392           if (identity)
2393                     sta->identity = os_strdup(identity);
2394           else
2395                     sta->identity = NULL;
2396 
2397           os_free(sta->radius_cui);
2398           if (radius_cui)
2399                     sta->radius_cui = os_strdup(radius_cui);
2400           else
2401                     sta->radius_cui = NULL;
2402 
2403           if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval)
2404                     sta->acct_interim_interval = acct_interim_interval;
2405           if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT) {
2406                     sta->session_timeout_set = 1;
2407                     os_get_reltime(&sta->session_timeout);
2408                     sta->session_timeout.sec += session_timeout;
2409                     ap_sta_session_timeout(hapd, sta, session_timeout);
2410           } else {
2411                     sta->session_timeout_set = 0;
2412                     ap_sta_no_session_timeout(hapd, sta);
2413           }
2414 
2415           return 0;
2416 }
2417 
2418 
2419 #ifdef CONFIG_PASN
2420 #ifdef CONFIG_FILS
2421 
pasn_fils_auth_resp(struct hostapd_data * hapd,struct sta_info * sta,u16 status,struct wpabuf * erp_resp,const u8 * msk,size_t msk_len)2422 static void pasn_fils_auth_resp(struct hostapd_data *hapd,
2423                                         struct sta_info *sta, u16 status,
2424                                         struct wpabuf *erp_resp,
2425                                         const u8 *msk, size_t msk_len)
2426 {
2427           struct pasn_data *pasn = sta->pasn;
2428           struct pasn_fils *fils = &pasn->fils;
2429           u8 pmk[PMK_LEN_MAX];
2430           size_t pmk_len;
2431           int ret;
2432 
2433           wpa_printf(MSG_DEBUG, "PASN: FILS: Handle AS response - status=%u",
2434                        status);
2435 
2436           if (status != WLAN_STATUS_SUCCESS)
2437                     goto fail;
2438 
2439           if (!pasn->secret) {
2440                     wpa_printf(MSG_DEBUG, "PASN: FILS: Missing secret");
2441                     goto fail;
2442           }
2443 
2444           if (random_get_bytes(fils->anonce, FILS_NONCE_LEN) < 0) {
2445                     wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to get ANonce");
2446                     goto fail;
2447           }
2448 
2449           wpa_hexdump(MSG_DEBUG, "RSN: Generated FILS ANonce",
2450                         fils->anonce, FILS_NONCE_LEN);
2451 
2452           ret = fils_rmsk_to_pmk(pasn_get_akmp(pasn), msk, msk_len, fils->nonce,
2453                                      fils->anonce, NULL, 0, pmk, &pmk_len);
2454           if (ret) {
2455                     wpa_printf(MSG_DEBUG, "FILS: Failed to derive PMK");
2456                     goto fail;
2457           }
2458 
2459           ret = pasn_pmk_to_ptk(pmk, pmk_len, sta->addr, hapd->own_addr,
2460                                     wpabuf_head(pasn->secret),
2461                                     wpabuf_len(pasn->secret),
2462                                     pasn_get_ptk(sta->pasn), pasn_get_akmp(sta->pasn),
2463                                     pasn_get_cipher(sta->pasn), sta->pasn->kdk_len);
2464           if (ret) {
2465                     wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to derive PTK");
2466                     goto fail;
2467           }
2468 
2469           if (pasn->secure_ltf) {
2470                     ret = wpa_ltf_keyseed(pasn_get_ptk(pasn), pasn_get_akmp(pasn),
2471                                               pasn_get_cipher(pasn));
2472                     if (ret) {
2473                               wpa_printf(MSG_DEBUG,
2474                                            "PASN: FILS: Failed to derive LTF keyseed");
2475                               goto fail;
2476                     }
2477           }
2478 
2479           wpa_printf(MSG_DEBUG, "PASN: PTK successfully derived");
2480 
2481           wpabuf_free(pasn->secret);
2482           pasn->secret = NULL;
2483 
2484           fils->erp_resp = erp_resp;
2485           ret = handle_auth_pasn_resp(sta->pasn, hapd->own_addr, sta->addr, NULL,
2486                                             WLAN_STATUS_SUCCESS);
2487           fils->erp_resp = NULL;
2488 
2489           if (ret) {
2490                     wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to send response");
2491                     goto fail;
2492           }
2493 
2494           fils->state = PASN_FILS_STATE_COMPLETE;
2495           return;
2496 fail:
2497           ap_free_sta(hapd, sta);
2498 }
2499 
2500 
pasn_wd_handle_fils(struct hostapd_data * hapd,struct sta_info * sta,struct wpabuf * wd)2501 static int pasn_wd_handle_fils(struct hostapd_data *hapd, struct sta_info *sta,
2502                                      struct wpabuf *wd)
2503 {
2504 #ifdef CONFIG_NO_RADIUS
2505           wpa_printf(MSG_DEBUG, "PASN: FILS: RADIUS is not configured. Fail");
2506           return -1;
2507 #else /* CONFIG_NO_RADIUS */
2508           struct pasn_data *pasn = sta->pasn;
2509           struct pasn_fils *fils = &pasn->fils;
2510           struct ieee802_11_elems elems;
2511           struct wpa_ie_data rsne_data;
2512           struct wpabuf *fils_wd;
2513           const u8 *data;
2514           size_t buf_len;
2515           u16 alg, seq, status;
2516           int ret;
2517 
2518           if (fils->state != PASN_FILS_STATE_NONE) {
2519                     wpa_printf(MSG_DEBUG, "PASN: FILS: Not expecting wrapped data");
2520                     return -1;
2521           }
2522 
2523           if (!wd) {
2524                     wpa_printf(MSG_DEBUG, "PASN: FILS: No wrapped data");
2525                     return -1;
2526           }
2527 
2528           data = wpabuf_head_u8(wd);
2529           buf_len = wpabuf_len(wd);
2530 
2531           if (buf_len < 6) {
2532                     wpa_printf(MSG_DEBUG, "PASN: FILS: Buffer too short. len=%zu",
2533                                  buf_len);
2534                     return -1;
2535           }
2536 
2537           alg = WPA_GET_LE16(data);
2538           seq = WPA_GET_LE16(data + 2);
2539           status = WPA_GET_LE16(data + 4);
2540 
2541           wpa_printf(MSG_DEBUG, "PASN: FILS: alg=%u, seq=%u, status=%u",
2542                        alg, seq, status);
2543 
2544           if (alg != WLAN_AUTH_FILS_SK || seq != 1 ||
2545               status != WLAN_STATUS_SUCCESS) {
2546                     wpa_printf(MSG_DEBUG,
2547                                  "PASN: FILS: Dropping peer authentication");
2548                     return -1;
2549           }
2550 
2551           data += 6;
2552           buf_len -= 6;
2553 
2554           if (ieee802_11_parse_elems(data, buf_len, &elems, 1) == ParseFailed) {
2555                     wpa_printf(MSG_DEBUG, "PASN: FILS: Could not parse elements");
2556                     return -1;
2557           }
2558 
2559           if (!elems.rsn_ie || !elems.fils_nonce || !elems.fils_nonce ||
2560               !elems.wrapped_data || !elems.fils_session) {
2561                     wpa_printf(MSG_DEBUG, "PASN: FILS: Missing IEs");
2562                     return -1;
2563           }
2564 
2565           ret = wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
2566                                            &rsne_data);
2567           if (ret) {
2568                     wpa_printf(MSG_DEBUG, "PASN: FILS: Failed parsing RSNE");
2569                     return -1;
2570           }
2571 
2572           ret = wpa_pasn_validate_rsne(&rsne_data);
2573           if (ret) {
2574                     wpa_printf(MSG_DEBUG, "PASN: FILS: Failed validating RSNE");
2575                     return -1;
2576           }
2577 
2578           if (rsne_data.num_pmkid) {
2579                     wpa_printf(MSG_DEBUG,
2580                                  "PASN: FILS: Not expecting PMKID in RSNE");
2581                     return -1;
2582           }
2583 
2584           wpa_hexdump(MSG_DEBUG, "PASN: FILS: Nonce", elems.fils_nonce,
2585                         FILS_NONCE_LEN);
2586           os_memcpy(fils->nonce, elems.fils_nonce, FILS_NONCE_LEN);
2587 
2588           wpa_hexdump(MSG_DEBUG, "PASN: FILS: Session", elems.fils_session,
2589                         FILS_SESSION_LEN);
2590           os_memcpy(fils->session, elems.fils_session, FILS_SESSION_LEN);
2591 
2592           fils_wd = ieee802_11_defrag(elems.wrapped_data, elems.wrapped_data_len,
2593                                             true);
2594 
2595           if (!fils_wd) {
2596                     wpa_printf(MSG_DEBUG, "PASN: FILS: Missing wrapped data");
2597                     return -1;
2598           }
2599 
2600           if (!sta->eapol_sm)
2601                     sta->eapol_sm = ieee802_1x_alloc_eapol_sm(hapd, sta);
2602 
2603           wpa_printf(MSG_DEBUG,
2604                        "PASN: FILS: Forward EAP-Initiate/Re-auth to AS");
2605 
2606           ieee802_1x_encapsulate_radius(hapd, sta, wpabuf_head(fils_wd),
2607                                               wpabuf_len(fils_wd));
2608 
2609           sta->flags |= WLAN_STA_PENDING_PASN_FILS_ERP;
2610 
2611           fils->state = PASN_FILS_STATE_PENDING_AS;
2612 
2613           /*
2614            * Calculate pending PMKID here so that we do not need to maintain a
2615            * copy of the EAP-Initiate/Reautt message.
2616            */
2617           fils_pmkid_erp(pasn_get_akmp(pasn),
2618                            wpabuf_head(fils_wd), wpabuf_len(fils_wd),
2619                            fils->erp_pmkid);
2620 
2621           wpabuf_free(fils_wd);
2622           return 0;
2623 #endif /* CONFIG_NO_RADIUS */
2624 }
2625 
2626 #endif /* CONFIG_FILS */
2627 
2628 
hapd_pasn_send_mlme(void * ctx,const u8 * data,size_t data_len,int noack,unsigned int freq,unsigned int wait)2629 static int hapd_pasn_send_mlme(void *ctx, const u8 *data, size_t data_len,
2630                                      int noack, unsigned int freq, unsigned int wait)
2631 {
2632           struct hostapd_data *hapd = ctx;
2633 
2634           return hostapd_drv_send_mlme(hapd, data, data_len, 0, NULL, 0, 0);
2635 }
2636 
2637 
hapd_initialize_pasn(struct hostapd_data * hapd,struct sta_info * sta)2638 static void hapd_initialize_pasn(struct hostapd_data *hapd,
2639                                          struct sta_info *sta)
2640 {
2641           struct pasn_data *pasn = sta->pasn;
2642 
2643           pasn_register_callbacks(pasn, hapd, hapd_pasn_send_mlme, NULL);
2644           pasn_set_bssid(pasn, hapd->own_addr);
2645           pasn_set_own_addr(pasn, hapd->own_addr);
2646           pasn_set_peer_addr(pasn, sta->addr);
2647           pasn_set_wpa_key_mgmt(pasn, hapd->conf->wpa_key_mgmt);
2648           pasn_set_rsn_pairwise(pasn, hapd->conf->rsn_pairwise);
2649           pasn->pasn_groups = hapd->conf->pasn_groups;
2650           pasn->noauth = hapd->conf->pasn_noauth;
2651           if (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF_AP)
2652                     pasn_enable_kdk_derivation(pasn);
2653 
2654 #ifdef CONFIG_TESTING_OPTIONS
2655           pasn->corrupt_mic = hapd->conf->pasn_corrupt_mic;
2656           if (hapd->conf->force_kdk_derivation)
2657                     pasn_enable_kdk_derivation(pasn);
2658 #endif /* CONFIG_TESTING_OPTIONS */
2659           pasn->use_anti_clogging = use_anti_clogging(hapd);
2660           pasn_set_password(pasn, sae_get_password(hapd, sta, NULL, NULL,
2661                                                              &pasn->pt, NULL));
2662           pasn->rsn_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &pasn->rsn_ie_len);
2663           pasn_set_rsnxe_ie(pasn, hostapd_wpa_ie(hapd, WLAN_EID_RSNX));
2664           pasn->disable_pmksa_caching = hapd->conf->disable_pmksa_caching;
2665           pasn_set_responder_pmksa(pasn,
2666                                          wpa_auth_get_pmksa_cache(hapd->wpa_auth));
2667 
2668           pasn->comeback_after = hapd->conf->pasn_comeback_after;
2669           pasn->comeback_idx = hapd->comeback_idx;
2670           pasn->comeback_key =  hapd->comeback_key;
2671           pasn->comeback_pending_idx = hapd->comeback_pending_idx;
2672 }
2673 
2674 
pasn_set_keys_from_cache(struct hostapd_data * hapd,const u8 * own_addr,const u8 * sta_addr,int cipher,int akmp)2675 static int pasn_set_keys_from_cache(struct hostapd_data *hapd,
2676                                             const u8 *own_addr, const u8 *sta_addr,
2677                                             int cipher, int akmp)
2678 {
2679           struct ptksa_cache_entry *entry;
2680 
2681           entry = ptksa_cache_get(hapd->ptksa, sta_addr, cipher);
2682           if (!entry) {
2683                     wpa_printf(MSG_DEBUG, "PASN: peer " MACSTR
2684                                  " not present in PTKSA cache", MAC2STR(sta_addr));
2685                     return -1;
2686           }
2687 
2688           if (!ether_addr_equal(entry->own_addr, own_addr)) {
2689                     wpa_printf(MSG_DEBUG,
2690                                  "PASN: own addr " MACSTR " and PTKSA entry own addr "
2691                                  MACSTR " differ",
2692                                  MAC2STR(own_addr), MAC2STR(entry->own_addr));
2693                     return -1;
2694           }
2695 
2696           wpa_printf(MSG_DEBUG, "PASN: " MACSTR " present in PTKSA cache",
2697                        MAC2STR(sta_addr));
2698           hostapd_drv_set_secure_ranging_ctx(hapd, own_addr, sta_addr, cipher,
2699                                                      entry->ptk.tk_len, entry->ptk.tk,
2700                                                      entry->ptk.ltf_keyseed_len,
2701                                                      entry->ptk.ltf_keyseed, 0);
2702 
2703           return 0;
2704 }
2705 
2706 
hapd_pasn_update_params(struct hostapd_data * hapd,struct sta_info * sta,const struct ieee80211_mgmt * mgmt,size_t len)2707 static void hapd_pasn_update_params(struct hostapd_data *hapd,
2708                                             struct sta_info *sta,
2709                                             const struct ieee80211_mgmt *mgmt,
2710                                             size_t len)
2711 {
2712           struct pasn_data *pasn = sta->pasn;
2713           struct ieee802_11_elems elems;
2714           struct wpa_ie_data rsn_data;
2715 #ifdef CONFIG_FILS
2716           struct wpa_pasn_params_data pasn_params;
2717           struct wpabuf *wrapped_data = NULL;
2718 #endif /* CONFIG_FILS */
2719           int akmp;
2720 
2721           if (ieee802_11_parse_elems(mgmt->u.auth.variable,
2722                                            len - offsetof(struct ieee80211_mgmt,
2723                                                               u.auth.variable),
2724                                            &elems, 0) == ParseFailed) {
2725                     wpa_printf(MSG_DEBUG,
2726                                  "PASN: Failed parsing Authentication frame");
2727                     return;
2728           }
2729 
2730           if (!elems.rsn_ie ||
2731               wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
2732                                          &rsn_data)) {
2733                     wpa_printf(MSG_DEBUG, "PASN: Failed parsing RSNE");
2734                     return;
2735           }
2736 
2737           if (!(rsn_data.key_mgmt & pasn->wpa_key_mgmt) ||
2738               !(rsn_data.pairwise_cipher & pasn->rsn_pairwise)) {
2739                     wpa_printf(MSG_DEBUG, "PASN: Mismatch in AKMP/cipher");
2740                     return;
2741           }
2742 
2743           pasn_set_akmp(pasn, rsn_data.key_mgmt);
2744           pasn_set_cipher(pasn, rsn_data.pairwise_cipher);
2745 
2746           if (pasn->derive_kdk &&
2747               !ieee802_11_rsnx_capab_len(elems.rsnxe, elems.rsnxe_len,
2748                                                WLAN_RSNX_CAPAB_SECURE_LTF))
2749                     pasn_disable_kdk_derivation(pasn);
2750 #ifdef CONFIG_TESTING_OPTIONS
2751           if (hapd->conf->force_kdk_derivation)
2752                     pasn_enable_kdk_derivation(pasn);
2753 #endif /* CONFIG_TESTING_OPTIONS */
2754           akmp = pasn_get_akmp(pasn);
2755 
2756           if (wpa_key_mgmt_ft(akmp) && rsn_data.num_pmkid) {
2757 #ifdef CONFIG_IEEE80211R_AP
2758                     pasn->pmk_r1_len = 0;
2759                     wpa_ft_fetch_pmk_r1(hapd->wpa_auth, sta->addr,
2760                                             rsn_data.pmkid,
2761                                             pasn->pmk_r1, &pasn->pmk_r1_len, NULL,
2762                                             NULL, NULL, NULL,
2763                                             NULL, NULL, NULL);
2764 #endif /* CONFIG_IEEE80211R_AP */
2765           }
2766 #ifdef CONFIG_FILS
2767           if (akmp != WPA_KEY_MGMT_FILS_SHA256 &&
2768               akmp != WPA_KEY_MGMT_FILS_SHA384)
2769                     return;
2770           if (!elems.pasn_params ||
2771               wpa_pasn_parse_parameter_ie(elems.pasn_params - 3,
2772                                                   elems.pasn_params_len + 3,
2773                                                   false, &pasn_params)) {
2774                     wpa_printf(MSG_DEBUG,
2775                                  "PASN: Failed validation of PASN Parameters element");
2776                     return;
2777           }
2778           if (pasn_params.wrapped_data_format != WPA_PASN_WRAPPED_DATA_NO) {
2779                     wrapped_data = ieee802_11_defrag(elems.wrapped_data,
2780                                                              elems.wrapped_data_len, true);
2781                     if (!wrapped_data) {
2782                               wpa_printf(MSG_DEBUG, "PASN: Missing wrapped data");
2783                               return;
2784                     }
2785                     if (pasn_wd_handle_fils(hapd, sta, wrapped_data))
2786                               wpa_printf(MSG_DEBUG,
2787                                            "PASN: Failed processing FILS wrapped data");
2788                     else
2789                               pasn->fils_wd_valid = true;
2790           }
2791           wpabuf_free(wrapped_data);
2792 #endif /* CONFIG_FILS */
2793 }
2794 
2795 
handle_auth_pasn(struct hostapd_data * hapd,struct sta_info * sta,const struct ieee80211_mgmt * mgmt,size_t len,u16 trans_seq,u16 status)2796 static void handle_auth_pasn(struct hostapd_data *hapd, struct sta_info *sta,
2797                                    const struct ieee80211_mgmt *mgmt, size_t len,
2798                                    u16 trans_seq, u16 status)
2799 {
2800           if (hapd->conf->wpa != WPA_PROTO_RSN) {
2801                     wpa_printf(MSG_INFO, "PASN: RSN is not configured");
2802                     return;
2803           }
2804 
2805           wpa_printf(MSG_INFO, "PASN authentication: sta=" MACSTR,
2806                        MAC2STR(sta->addr));
2807 
2808           if (trans_seq == 1) {
2809                     if (sta->pasn) {
2810                               wpa_printf(MSG_DEBUG,
2811                                            "PASN: Not expecting transaction == 1");
2812                               return;
2813                     }
2814 
2815                     if (status != WLAN_STATUS_SUCCESS) {
2816                               wpa_printf(MSG_DEBUG,
2817                                            "PASN: Failure status in transaction == 1");
2818                               return;
2819                     }
2820 
2821                     sta->pasn = pasn_data_init();
2822                     if (!sta->pasn) {
2823                               wpa_printf(MSG_DEBUG,
2824                                            "PASN: Failed to allocate PASN context");
2825                               return;
2826                     }
2827 
2828                     hapd_initialize_pasn(hapd, sta);
2829 
2830                     hapd_pasn_update_params(hapd, sta, mgmt, len);
2831                     if (handle_auth_pasn_1(sta->pasn, hapd->own_addr,
2832                                                sta->addr, mgmt, len) < 0)
2833                               ap_free_sta(hapd, sta);
2834           } else if (trans_seq == 3) {
2835                     if (!sta->pasn) {
2836                               wpa_printf(MSG_DEBUG,
2837                                            "PASN: Not expecting transaction == 3");
2838                               return;
2839                     }
2840 
2841                     if (status != WLAN_STATUS_SUCCESS) {
2842                               wpa_printf(MSG_DEBUG,
2843                                            "PASN: Failure status in transaction == 3");
2844                               ap_free_sta_pasn(hapd, sta);
2845                               return;
2846                     }
2847 
2848                     if (handle_auth_pasn_3(sta->pasn, hapd->own_addr,
2849                                                sta->addr, mgmt, len) == 0) {
2850                               ptksa_cache_add(hapd->ptksa, hapd->own_addr, sta->addr,
2851                                                   pasn_get_cipher(sta->pasn), 43200,
2852                                                   pasn_get_ptk(sta->pasn), NULL, NULL,
2853                                                   pasn_get_akmp(sta->pasn));
2854 
2855                               pasn_set_keys_from_cache(hapd, hapd->own_addr,
2856                                                              sta->addr,
2857                                                              pasn_get_cipher(sta->pasn),
2858                                                              pasn_get_akmp(sta->pasn));
2859                     }
2860                     ap_free_sta(hapd, sta);
2861           } else {
2862                     wpa_printf(MSG_DEBUG,
2863                                  "PASN: Invalid transaction %u - ignore", trans_seq);
2864           }
2865 }
2866 
2867 #endif /* CONFIG_PASN */
2868 
2869 
handle_auth(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len,int rssi,int from_queue)2870 static void handle_auth(struct hostapd_data *hapd,
2871                               const struct ieee80211_mgmt *mgmt, size_t len,
2872                               int rssi, int from_queue)
2873 {
2874           u16 auth_alg, auth_transaction, status_code;
2875           u16 resp = WLAN_STATUS_SUCCESS;
2876           struct sta_info *sta = NULL;
2877           int res, reply_res;
2878           u16 fc;
2879           const u8 *challenge = NULL;
2880           u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
2881           size_t resp_ies_len = 0;
2882           u16 seq_ctrl;
2883           struct radius_sta rad_info;
2884           const u8 *dst, *sa;
2885 #ifdef CONFIG_IEEE80211BE
2886           bool mld_sta = false;
2887 #endif /* CONFIG_IEEE80211BE */
2888 
2889           if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
2890                     wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
2891                                  (unsigned long) len);
2892                     return;
2893           }
2894 
2895 #ifdef CONFIG_TESTING_OPTIONS
2896           if (hapd->iconf->ignore_auth_probability > 0.0 &&
2897               drand48() < hapd->iconf->ignore_auth_probability) {
2898                     wpa_printf(MSG_INFO,
2899                                  "TESTING: ignoring auth frame from " MACSTR,
2900                                  MAC2STR(mgmt->sa));
2901                     return;
2902           }
2903 #endif /* CONFIG_TESTING_OPTIONS */
2904 
2905           sa = mgmt->sa;
2906 #ifdef CONFIG_IEEE80211BE
2907           /*
2908            * Handle MLO authentication before the station is added to hostapd and
2909            * the driver so that the station MLD MAC address would be used in both
2910            * hostapd and the driver.
2911            */
2912           sa = hostapd_process_ml_auth(hapd, mgmt, len);
2913           if (sa)
2914                     mld_sta = true;
2915           else
2916                     sa = mgmt->sa;
2917 #endif /* CONFIG_IEEE80211BE */
2918 
2919           auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
2920           auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
2921           status_code = le_to_host16(mgmt->u.auth.status_code);
2922           fc = le_to_host16(mgmt->frame_control);
2923           seq_ctrl = le_to_host16(mgmt->seq_ctrl);
2924 
2925           if (len >= IEEE80211_HDRLEN + sizeof(mgmt->u.auth) +
2926               2 + WLAN_AUTH_CHALLENGE_LEN &&
2927               mgmt->u.auth.variable[0] == WLAN_EID_CHALLENGE &&
2928               mgmt->u.auth.variable[1] == WLAN_AUTH_CHALLENGE_LEN)
2929                     challenge = &mgmt->u.auth.variable[2];
2930 
2931           wpa_printf(MSG_DEBUG, "authentication: STA=" MACSTR " auth_alg=%d "
2932                        "auth_transaction=%d status_code=%d wep=%d%s "
2933                        "seq_ctrl=0x%x%s%s",
2934                        MAC2STR(sa), auth_alg, auth_transaction,
2935                        status_code, !!(fc & WLAN_FC_ISWEP),
2936                        challenge ? " challenge" : "",
2937                        seq_ctrl, (fc & WLAN_FC_RETRY) ? " retry" : "",
2938                        from_queue ? " (from queue)" : "");
2939 
2940 #ifdef CONFIG_NO_RC4
2941           if (auth_alg == WLAN_AUTH_SHARED_KEY) {
2942                     wpa_printf(MSG_INFO,
2943                                  "Unsupported authentication algorithm (%d)",
2944                                  auth_alg);
2945                     resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
2946                     goto fail;
2947           }
2948 #endif /* CONFIG_NO_RC4 */
2949 
2950           if (hapd->tkip_countermeasures) {
2951                     wpa_printf(MSG_DEBUG,
2952                                  "Ongoing TKIP countermeasures (Michael MIC failure) - reject authentication");
2953                     resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2954                     goto fail;
2955           }
2956 
2957           if (!(((hapd->conf->auth_algs & WPA_AUTH_ALG_OPEN) &&
2958                  auth_alg == WLAN_AUTH_OPEN) ||
2959 #ifdef CONFIG_IEEE80211R_AP
2960                 (hapd->conf->wpa && wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt) &&
2961                  auth_alg == WLAN_AUTH_FT) ||
2962 #endif /* CONFIG_IEEE80211R_AP */
2963 #ifdef CONFIG_SAE
2964                 (hapd->conf->wpa && wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
2965                  auth_alg == WLAN_AUTH_SAE) ||
2966 #endif /* CONFIG_SAE */
2967 #ifdef CONFIG_FILS
2968                 (hapd->conf->wpa && wpa_key_mgmt_fils(hapd->conf->wpa_key_mgmt) &&
2969                  auth_alg == WLAN_AUTH_FILS_SK) ||
2970                 (hapd->conf->wpa && wpa_key_mgmt_fils(hapd->conf->wpa_key_mgmt) &&
2971                  hapd->conf->fils_dh_group &&
2972                  auth_alg == WLAN_AUTH_FILS_SK_PFS) ||
2973 #endif /* CONFIG_FILS */
2974 #ifdef CONFIG_PASN
2975                 (hapd->conf->wpa &&
2976                  (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_PASN) &&
2977                  auth_alg == WLAN_AUTH_PASN) ||
2978 #endif /* CONFIG_PASN */
2979                 ((hapd->conf->auth_algs & WPA_AUTH_ALG_SHARED) &&
2980                  auth_alg == WLAN_AUTH_SHARED_KEY))) {
2981                     wpa_printf(MSG_INFO, "Unsupported authentication algorithm (%d)",
2982                                  auth_alg);
2983                     resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
2984                     goto fail;
2985           }
2986 
2987           if (!(auth_transaction == 1 || auth_alg == WLAN_AUTH_SAE ||
2988 #ifdef CONFIG_PASN
2989                 (auth_alg == WLAN_AUTH_PASN && auth_transaction == 3) ||
2990 #endif /* CONFIG_PASN */
2991                 (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) {
2992                     wpa_printf(MSG_INFO, "Unknown authentication transaction number (%d)",
2993                                  auth_transaction);
2994                     resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
2995                     goto fail;
2996           }
2997 
2998           if (ether_addr_equal(mgmt->sa, hapd->own_addr)) {
2999                     wpa_printf(MSG_INFO, "Station " MACSTR " not allowed to authenticate",
3000                                  MAC2STR(sa));
3001                     resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
3002                     goto fail;
3003           }
3004 
3005 #ifdef CONFIG_IEEE80211BE
3006           if (mld_sta &&
3007               (ether_addr_equal(sa, hapd->own_addr) ||
3008                ether_addr_equal(sa, hapd->mld->mld_addr))) {
3009                     wpa_printf(MSG_INFO,
3010                                  "Station " MACSTR " not allowed to authenticate",
3011                                  MAC2STR(sa));
3012                     resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
3013                     goto fail;
3014           }
3015 #endif /* CONFIG_IEEE80211BE */
3016 
3017           if (hapd->conf->no_auth_if_seen_on) {
3018                     struct hostapd_data *other;
3019 
3020                     other = sta_track_seen_on(hapd->iface, sa,
3021                                                     hapd->conf->no_auth_if_seen_on);
3022                     if (other) {
3023                               u8 *pos;
3024                               u32 info;
3025                               u8 op_class, channel, phytype;
3026 
3027                               wpa_printf(MSG_DEBUG, "%s: Reject authentication from "
3028                                            MACSTR " since STA has been seen on %s",
3029                                            hapd->conf->iface, MAC2STR(sa),
3030                                            hapd->conf->no_auth_if_seen_on);
3031 
3032                               resp = WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION;
3033                               pos = &resp_ies[0];
3034                               *pos++ = WLAN_EID_NEIGHBOR_REPORT;
3035                               *pos++ = 13;
3036                               os_memcpy(pos, other->own_addr, ETH_ALEN);
3037                               pos += ETH_ALEN;
3038                               info = 0; /* TODO: BSSID Information */
3039                               WPA_PUT_LE32(pos, info);
3040                               pos += 4;
3041                               if (other->iconf->hw_mode == HOSTAPD_MODE_IEEE80211AD)
3042                                         phytype = 8; /* dmg */
3043                               else if (other->iconf->ieee80211ac)
3044                                         phytype = 9; /* vht */
3045                               else if (other->iconf->ieee80211n)
3046                                         phytype = 7; /* ht */
3047                               else if (other->iconf->hw_mode ==
3048                                          HOSTAPD_MODE_IEEE80211A)
3049                                         phytype = 4; /* ofdm */
3050                               else if (other->iconf->hw_mode ==
3051                                          HOSTAPD_MODE_IEEE80211G)
3052                                         phytype = 6; /* erp */
3053                               else
3054                                         phytype = 5; /* hrdsss */
3055                               if (ieee80211_freq_to_channel_ext(
3056                                             hostapd_hw_get_freq(other,
3057                                                                       other->iconf->channel),
3058                                             other->iconf->secondary_channel,
3059                                             other->iconf->ieee80211ac,
3060                                             &op_class, &channel) == NUM_HOSTAPD_MODES) {
3061                                         op_class = 0;
3062                                         channel = other->iconf->channel;
3063                               }
3064                               *pos++ = op_class;
3065                               *pos++ = channel;
3066                               *pos++ = phytype;
3067                               resp_ies_len = pos - &resp_ies[0];
3068                               goto fail;
3069                     }
3070           }
3071 
3072           res = ieee802_11_allowed_address(hapd, sa, (const u8 *) mgmt, len,
3073                                                    &rad_info);
3074           if (res == HOSTAPD_ACL_REJECT) {
3075                     wpa_msg(hapd->msg_ctx, MSG_DEBUG,
3076                               "Ignore Authentication frame from " MACSTR
3077                               " due to ACL reject", MAC2STR(sa));
3078                     resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
3079                     goto fail;
3080           }
3081           if (res == HOSTAPD_ACL_PENDING)
3082                     return;
3083 
3084 #ifdef CONFIG_SAE
3085           if (auth_alg == WLAN_AUTH_SAE && !from_queue &&
3086               (auth_transaction == 1 ||
3087                (auth_transaction == 2 && auth_sae_queued_addr(hapd, sa)))) {
3088                     /* Handle SAE Authentication commit message through a queue to
3089                      * provide more control for postponing the needed heavy
3090                      * processing under a possible DoS attack scenario. In addition,
3091                      * queue SAE Authentication confirm message if there happens to
3092                      * be a queued commit message from the same peer. This is needed
3093                      * to avoid reordering Authentication frames within the same
3094                      * SAE exchange. */
3095                     auth_sae_queue(hapd, mgmt, len, rssi);
3096                     return;
3097           }
3098 #endif /* CONFIG_SAE */
3099 
3100           sta = ap_get_sta(hapd, sa);
3101           if (sta) {
3102                     sta->flags &= ~WLAN_STA_PENDING_FILS_ERP;
3103                     sta->ft_over_ds = 0;
3104                     if ((fc & WLAN_FC_RETRY) &&
3105                         sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
3106                         sta->last_seq_ctrl == seq_ctrl &&
3107                         sta->last_subtype == WLAN_FC_STYPE_AUTH) {
3108                               hostapd_logger(hapd, sta->addr,
3109                                                HOSTAPD_MODULE_IEEE80211,
3110                                                HOSTAPD_LEVEL_DEBUG,
3111                                                "Drop repeated authentication frame seq_ctrl=0x%x",
3112                                                seq_ctrl);
3113                               return;
3114                     }
3115 #ifdef CONFIG_PASN
3116                     if (auth_alg == WLAN_AUTH_PASN &&
3117                         (sta->flags & WLAN_STA_ASSOC)) {
3118                               wpa_printf(MSG_DEBUG,
3119                                            "PASN: auth: Existing station: " MACSTR,
3120                                            MAC2STR(sta->addr));
3121                               return;
3122                     }
3123 #endif /* CONFIG_PASN */
3124           } else {
3125 #ifdef CONFIG_MESH
3126                     if (hapd->conf->mesh & MESH_ENABLED) {
3127                               /* if the mesh peer is not available, we don't do auth.
3128                                */
3129                               wpa_printf(MSG_DEBUG, "Mesh peer " MACSTR
3130                                            " not yet known - drop Authentication frame",
3131                                            MAC2STR(sa));
3132                               /*
3133                                * Save a copy of the frame so that it can be processed
3134                                * if a new peer entry is added shortly after this.
3135                                */
3136                               wpabuf_free(hapd->mesh_pending_auth);
3137                               hapd->mesh_pending_auth = wpabuf_alloc_copy(mgmt, len);
3138                               os_get_reltime(&hapd->mesh_pending_auth_time);
3139                               return;
3140                     }
3141 #endif /* CONFIG_MESH */
3142 
3143                     sta = ap_sta_add(hapd, sa);
3144                     if (!sta) {
3145                               wpa_printf(MSG_DEBUG, "ap_sta_add() failed");
3146                               resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
3147                               goto fail;
3148                     }
3149           }
3150 
3151 #ifdef CONFIG_IEEE80211BE
3152           /* Set the non-AP MLD information based on the initial Authentication
3153            * frame. Once the STA entry has been added to the driver, the driver
3154            * will translate addresses in the frame and we need to avoid overriding
3155            * peer_addr based on mgmt->sa which would have been translated to the
3156            * MLD MAC address. */
3157           if (!sta->added_unassoc && auth_transaction == 1) {
3158                     ap_sta_free_sta_profile(&sta->mld_info);
3159                     os_memset(&sta->mld_info, 0, sizeof(sta->mld_info));
3160 
3161                     if (mld_sta) {
3162                               u8 link_id = hapd->mld_link_id;
3163 
3164                               ap_sta_set_mld(sta, true);
3165                               sta->mld_assoc_link_id = link_id;
3166 
3167                               /*
3168                                * Set the MLD address as the station address and the
3169                                * station addresses.
3170                                */
3171                               os_memcpy(sta->mld_info.common_info.mld_addr, sa,
3172                                           ETH_ALEN);
3173                               os_memcpy(sta->mld_info.links[link_id].peer_addr,
3174                                           mgmt->sa, ETH_ALEN);
3175                               os_memcpy(sta->mld_info.links[link_id].local_addr,
3176                                           hapd->own_addr, ETH_ALEN);
3177                     }
3178           }
3179 #endif /* CONFIG_IEEE80211BE */
3180 
3181           sta->last_seq_ctrl = seq_ctrl;
3182           sta->last_subtype = WLAN_FC_STYPE_AUTH;
3183 #ifdef CONFIG_MBO
3184           sta->auth_rssi = rssi;
3185 #endif /* CONFIG_MBO */
3186 
3187           res = ieee802_11_set_radius_info(hapd, sta, res, &rad_info);
3188           if (res) {
3189                     wpa_printf(MSG_DEBUG, "ieee802_11_set_radius_info() failed");
3190                     resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
3191                     goto fail;
3192           }
3193 
3194           sta->flags &= ~WLAN_STA_PREAUTH;
3195           ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
3196 
3197           /*
3198            * If the driver supports full AP client state, add a station to the
3199            * driver before sending authentication reply to make sure the driver
3200            * has resources, and not to go through the entire authentication and
3201            * association handshake, and fail it at the end.
3202            *
3203            * If this is not the first transaction, in a multi-step authentication
3204            * algorithm, the station already exists in the driver
3205            * (sta->added_unassoc = 1) so skip it.
3206            *
3207            * In mesh mode, the station was already added to the driver when the
3208            * NEW_PEER_CANDIDATE event is received.
3209            *
3210            * If PMF was negotiated for the existing association, skip this to
3211            * avoid dropping the STA entry and the associated keys. This is needed
3212            * to allow the original connection work until the attempt can complete
3213            * (re)association, so that unprotected Authentication frame cannot be
3214            * used to bypass PMF protection.
3215            *
3216            * PASN authentication does not require adding/removing station to the
3217            * driver so skip this flow in case of PASN authentication.
3218            */
3219           if (FULL_AP_CLIENT_STATE_SUPP(hapd->iface->drv_flags) &&
3220               (!(sta->flags & WLAN_STA_MFP) || !ap_sta_is_authorized(sta)) &&
3221               !(hapd->conf->mesh & MESH_ENABLED) &&
3222               !(sta->added_unassoc) && auth_alg != WLAN_AUTH_PASN) {
3223                     if (ap_sta_re_add(hapd, sta) < 0) {
3224                               resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
3225                               goto fail;
3226                     }
3227           }
3228 
3229           switch (auth_alg) {
3230           case WLAN_AUTH_OPEN:
3231                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3232                                      HOSTAPD_LEVEL_DEBUG,
3233                                      "authentication OK (open system)");
3234                     sta->flags |= WLAN_STA_AUTH;
3235                     wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
3236                     sta->auth_alg = WLAN_AUTH_OPEN;
3237                     mlme_authenticate_indication(hapd, sta);
3238                     break;
3239 #ifdef CONFIG_WEP
3240 #ifndef CONFIG_NO_RC4
3241           case WLAN_AUTH_SHARED_KEY:
3242                     resp = auth_shared_key(hapd, sta, auth_transaction, challenge,
3243                                                fc & WLAN_FC_ISWEP);
3244                     if (resp != 0)
3245                               wpa_printf(MSG_DEBUG,
3246                                            "auth_shared_key() failed: status=%d", resp);
3247                     sta->auth_alg = WLAN_AUTH_SHARED_KEY;
3248                     mlme_authenticate_indication(hapd, sta);
3249                     if (sta->challenge && auth_transaction == 1) {
3250                               resp_ies[0] = WLAN_EID_CHALLENGE;
3251                               resp_ies[1] = WLAN_AUTH_CHALLENGE_LEN;
3252                               os_memcpy(resp_ies + 2, sta->challenge,
3253                                           WLAN_AUTH_CHALLENGE_LEN);
3254                               resp_ies_len = 2 + WLAN_AUTH_CHALLENGE_LEN;
3255                     }
3256                     break;
3257 #endif /* CONFIG_NO_RC4 */
3258 #endif /* CONFIG_WEP */
3259 #ifdef CONFIG_IEEE80211R_AP
3260           case WLAN_AUTH_FT:
3261                     sta->auth_alg = WLAN_AUTH_FT;
3262                     if (sta->wpa_sm == NULL)
3263                               sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
3264                                                                       sta->addr, NULL);
3265                     if (sta->wpa_sm == NULL) {
3266                               wpa_printf(MSG_DEBUG, "FT: Failed to initialize WPA "
3267                                            "state machine");
3268                               resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
3269                               goto fail;
3270                     }
3271                     wpa_ft_process_auth(sta->wpa_sm,
3272                                             auth_transaction, mgmt->u.auth.variable,
3273                                             len - IEEE80211_HDRLEN -
3274                                             sizeof(mgmt->u.auth),
3275                                             handle_auth_ft_finish, hapd);
3276                     /* handle_auth_ft_finish() callback will complete auth. */
3277                     return;
3278 #endif /* CONFIG_IEEE80211R_AP */
3279 #ifdef CONFIG_SAE
3280           case WLAN_AUTH_SAE:
3281 #ifdef CONFIG_MESH
3282                     if (status_code == WLAN_STATUS_SUCCESS &&
3283                         hapd->conf->mesh & MESH_ENABLED) {
3284                               if (sta->wpa_sm == NULL)
3285                                         sta->wpa_sm =
3286                                                   wpa_auth_sta_init(hapd->wpa_auth,
3287                                                                         sta->addr, NULL);
3288                               if (sta->wpa_sm == NULL) {
3289                                         wpa_printf(MSG_DEBUG,
3290                                                      "SAE: Failed to initialize WPA state machine");
3291                                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
3292                                         goto fail;
3293                               }
3294                     }
3295 #endif /* CONFIG_MESH */
3296                     handle_auth_sae(hapd, sta, mgmt, len, auth_transaction,
3297                                         status_code);
3298                     return;
3299 #endif /* CONFIG_SAE */
3300 #ifdef CONFIG_FILS
3301           case WLAN_AUTH_FILS_SK:
3302           case WLAN_AUTH_FILS_SK_PFS:
3303                     handle_auth_fils(hapd, sta, mgmt->u.auth.variable,
3304                                          len - IEEE80211_HDRLEN - sizeof(mgmt->u.auth),
3305                                          auth_alg, auth_transaction, status_code,
3306                                          handle_auth_fils_finish);
3307                     return;
3308 #endif /* CONFIG_FILS */
3309 #ifdef CONFIG_PASN
3310           case WLAN_AUTH_PASN:
3311                     handle_auth_pasn(hapd, sta, mgmt, len, auth_transaction,
3312                                          status_code);
3313                     return;
3314 #endif /* CONFIG_PASN */
3315           }
3316 
3317  fail:
3318           dst = mgmt->sa;
3319 
3320 #ifdef CONFIG_IEEE80211BE
3321           if (ap_sta_is_mld(hapd, sta))
3322                     dst = sta->addr;
3323 #endif /* CONFIG_IEEE80211BE */
3324 
3325           reply_res = send_auth_reply(hapd, sta, dst, auth_alg,
3326                                             auth_alg == WLAN_AUTH_SAE ?
3327                                             auth_transaction : auth_transaction + 1,
3328                                             resp, resp_ies, resp_ies_len,
3329                                             "handle-auth");
3330 
3331           if (sta && sta->added_unassoc && (resp != WLAN_STATUS_SUCCESS ||
3332                                                     reply_res != WLAN_STATUS_SUCCESS)) {
3333                     hostapd_drv_sta_remove(hapd, sta->addr);
3334                     sta->added_unassoc = 0;
3335           }
3336 }
3337 
3338 
hostapd_max_bssid_indicator(struct hostapd_data * hapd)3339 static u8 hostapd_max_bssid_indicator(struct hostapd_data *hapd)
3340 {
3341           size_t num_bss_nontx;
3342           u8 max_bssid_ind = 0;
3343 
3344           if (!hapd->iconf->mbssid || hapd->iface->num_bss <= 1)
3345                     return 0;
3346 
3347           num_bss_nontx = hapd->iface->num_bss - 1;
3348           while (num_bss_nontx > 0) {
3349                     max_bssid_ind++;
3350                     num_bss_nontx >>= 1;
3351           }
3352           return max_bssid_ind;
3353 }
3354 
3355 
hostapd_get_aid_word(struct hostapd_data * hapd,struct sta_info * sta,int i)3356 static u32 hostapd_get_aid_word(struct hostapd_data *hapd,
3357                                         struct sta_info *sta, int i)
3358 {
3359 #ifdef CONFIG_IEEE80211BE
3360           u32 aid_word = 0;
3361 
3362           /* Do not assign an AID that is in use on any of the affiliated links
3363            * when finding an AID for a non-AP MLD. */
3364           if (hapd->conf->mld_ap && sta->mld_info.mld_sta) {
3365                     int j;
3366 
3367                     for (j = 0; j < MAX_NUM_MLD_LINKS; j++) {
3368                               struct hostapd_data *link_bss;
3369 
3370                               if (!sta->mld_info.links[j].valid)
3371                                         continue;
3372 
3373                               link_bss = hostapd_mld_get_link_bss(hapd, j);
3374                               if (!link_bss) {
3375                                         /* This shouldn't happen, just skip */
3376                                         wpa_printf(MSG_ERROR,
3377                                                      "MLD: Failed to get link BSS for AID");
3378                                         continue;
3379                               }
3380 
3381                               aid_word |= link_bss->sta_aid[i];
3382                     }
3383 
3384                     return aid_word;
3385           }
3386 #endif /* CONFIG_IEEE80211BE */
3387 
3388           return hapd->sta_aid[i];
3389 }
3390 
3391 
hostapd_get_aid(struct hostapd_data * hapd,struct sta_info * sta)3392 int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta)
3393 {
3394           int i, j = 32, aid;
3395 
3396           /* Transmitted and non-transmitted BSSIDs share the same AID pool, so
3397            * use the shared storage in the transmitted BSS to find the next
3398            * available value. */
3399           hapd = hostapd_mbssid_get_tx_bss(hapd);
3400 
3401           /* get a unique AID */
3402           if (sta->aid > 0) {
3403                     wpa_printf(MSG_DEBUG, "  old AID %d", sta->aid);
3404                     return 0;
3405           }
3406 
3407           if (TEST_FAIL())
3408                     return -1;
3409 
3410           for (i = 0; i < AID_WORDS; i++) {
3411                     u32 aid_word = hostapd_get_aid_word(hapd, sta, i);
3412 
3413                     if (aid_word == (u32) -1)
3414                               continue;
3415                     for (j = 0; j < 32; j++) {
3416                               if (!(aid_word & BIT(j)))
3417                                         break;
3418                     }
3419                     if (j < 32)
3420                               break;
3421           }
3422           if (j == 32)
3423                     return -1;
3424           aid = i * 32 + j + (1 << hostapd_max_bssid_indicator(hapd));
3425           if (aid > 2007)
3426                     return -1;
3427 
3428           sta->aid = aid;
3429           hapd->sta_aid[i] |= BIT(j);
3430           wpa_printf(MSG_DEBUG, "  new AID %d", sta->aid);
3431           return 0;
3432 }
3433 
3434 
check_ssid(struct hostapd_data * hapd,struct sta_info * sta,const u8 * ssid_ie,size_t ssid_ie_len)3435 static u16 check_ssid(struct hostapd_data *hapd, struct sta_info *sta,
3436                           const u8 *ssid_ie, size_t ssid_ie_len)
3437 {
3438           if (ssid_ie == NULL)
3439                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
3440 
3441           if (ssid_ie_len != hapd->conf->ssid.ssid_len ||
3442               os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0) {
3443                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3444                                      HOSTAPD_LEVEL_INFO,
3445                                      "Station tried to associate with unknown SSID "
3446                                      "'%s'", wpa_ssid_txt(ssid_ie, ssid_ie_len));
3447                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
3448           }
3449 
3450           return WLAN_STATUS_SUCCESS;
3451 }
3452 
3453 
check_wmm(struct hostapd_data * hapd,struct sta_info * sta,const u8 * wmm_ie,size_t wmm_ie_len)3454 static u16 check_wmm(struct hostapd_data *hapd, struct sta_info *sta,
3455                          const u8 *wmm_ie, size_t wmm_ie_len)
3456 {
3457           sta->flags &= ~WLAN_STA_WMM;
3458           sta->qosinfo = 0;
3459           if (wmm_ie && hapd->conf->wmm_enabled) {
3460                     struct wmm_information_element *wmm;
3461 
3462                     if (!hostapd_eid_wmm_valid(hapd, wmm_ie, wmm_ie_len)) {
3463                               hostapd_logger(hapd, sta->addr,
3464                                                HOSTAPD_MODULE_WPA,
3465                                                HOSTAPD_LEVEL_DEBUG,
3466                                                "invalid WMM element in association "
3467                                                "request");
3468                               return WLAN_STATUS_UNSPECIFIED_FAILURE;
3469                     }
3470 
3471                     sta->flags |= WLAN_STA_WMM;
3472                     wmm = (struct wmm_information_element *) wmm_ie;
3473                     sta->qosinfo = wmm->qos_info;
3474           }
3475           return WLAN_STATUS_SUCCESS;
3476 }
3477 
check_multi_ap(struct hostapd_data * hapd,struct sta_info * sta,const u8 * multi_ap_ie,size_t multi_ap_len)3478 static u16 check_multi_ap(struct hostapd_data *hapd, struct sta_info *sta,
3479                                 const u8 *multi_ap_ie, size_t multi_ap_len)
3480 {
3481           struct multi_ap_params multi_ap;
3482           u16 status;
3483 
3484           sta->flags &= ~WLAN_STA_MULTI_AP;
3485 
3486           if (!hapd->conf->multi_ap)
3487                     return WLAN_STATUS_SUCCESS;
3488 
3489           if (!multi_ap_ie) {
3490                     if (!(hapd->conf->multi_ap & FRONTHAUL_BSS)) {
3491                               hostapd_logger(hapd, sta->addr,
3492                                                HOSTAPD_MODULE_IEEE80211,
3493                                                HOSTAPD_LEVEL_INFO,
3494                                                "Non-Multi-AP STA tries to associate with backhaul-only BSS");
3495                               return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
3496                     }
3497 
3498                     return WLAN_STATUS_SUCCESS;
3499           }
3500 
3501           status = check_multi_ap_ie(multi_ap_ie + 4, multi_ap_len - 4,
3502                                            &multi_ap);
3503           if (status != WLAN_STATUS_SUCCESS)
3504                     return status;
3505 
3506           if (multi_ap.capability && multi_ap.capability != MULTI_AP_BACKHAUL_STA)
3507                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3508                                      HOSTAPD_LEVEL_INFO,
3509                                      "Multi-AP IE with unexpected value 0x%02x",
3510                                      multi_ap.capability);
3511 
3512           if (multi_ap.profile == MULTI_AP_PROFILE_1 &&
3513               (hapd->conf->multi_ap_client_disallow &
3514                PROFILE1_CLIENT_ASSOC_DISALLOW)) {
3515                     hostapd_logger(hapd, sta->addr,
3516                                      HOSTAPD_MODULE_IEEE80211,
3517                                      HOSTAPD_LEVEL_INFO,
3518                                      "Multi-AP Profile-1 clients not allowed");
3519                     return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
3520           }
3521 
3522           if (multi_ap.profile >= MULTI_AP_PROFILE_2 &&
3523               (hapd->conf->multi_ap_client_disallow &
3524                PROFILE2_CLIENT_ASSOC_DISALLOW)) {
3525                     hostapd_logger(hapd, sta->addr,
3526                                      HOSTAPD_MODULE_IEEE80211,
3527                                      HOSTAPD_LEVEL_INFO,
3528                                      "Multi-AP Profile-2 clients not allowed");
3529                     return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
3530           }
3531 
3532           if (!(multi_ap.capability & MULTI_AP_BACKHAUL_STA)) {
3533                     if (hapd->conf->multi_ap & FRONTHAUL_BSS)
3534                               return WLAN_STATUS_SUCCESS;
3535 
3536                     hostapd_logger(hapd, sta->addr,
3537                                      HOSTAPD_MODULE_IEEE80211,
3538                                      HOSTAPD_LEVEL_INFO,
3539                                      "Non-Multi-AP STA tries to associate with backhaul-only BSS");
3540                     return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
3541           }
3542 
3543           if (!(hapd->conf->multi_ap & BACKHAUL_BSS))
3544                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3545                                      HOSTAPD_LEVEL_DEBUG,
3546                                      "Backhaul STA tries to associate with fronthaul-only BSS");
3547 
3548           sta->flags |= WLAN_STA_MULTI_AP;
3549           return WLAN_STATUS_SUCCESS;
3550 }
3551 
3552 
copy_supp_rates(struct hostapd_data * hapd,struct sta_info * sta,struct ieee802_11_elems * elems)3553 static u16 copy_supp_rates(struct hostapd_data *hapd, struct sta_info *sta,
3554                                  struct ieee802_11_elems *elems)
3555 {
3556           /* Supported rates not used in IEEE 802.11ad/DMG */
3557           if (hapd->iface->current_mode &&
3558               hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211AD)
3559                     return WLAN_STATUS_SUCCESS;
3560 
3561           if (!elems->supp_rates) {
3562                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3563                                      HOSTAPD_LEVEL_DEBUG,
3564                                      "No supported rates element in AssocReq");
3565                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
3566           }
3567 
3568           if (elems->supp_rates_len + elems->ext_supp_rates_len >
3569               sizeof(sta->supported_rates)) {
3570                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3571                                      HOSTAPD_LEVEL_DEBUG,
3572                                      "Invalid supported rates element length %d+%d",
3573                                      elems->supp_rates_len,
3574                                      elems->ext_supp_rates_len);
3575                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
3576           }
3577 
3578           sta->supported_rates_len = merge_byte_arrays(
3579                     sta->supported_rates, sizeof(sta->supported_rates),
3580                     elems->supp_rates, elems->supp_rates_len,
3581                     elems->ext_supp_rates, elems->ext_supp_rates_len);
3582 
3583           return WLAN_STATUS_SUCCESS;
3584 }
3585 
3586 
3587 #ifdef CONFIG_OWE
3588 
owe_group_supported(struct hostapd_data * hapd,u16 group)3589 static int owe_group_supported(struct hostapd_data *hapd, u16 group)
3590 {
3591           int i;
3592           int *groups = hapd->conf->owe_groups;
3593 
3594           if (group != 19 && group != 20 && group != 21)
3595                     return 0;
3596 
3597           if (!groups)
3598                     return 1;
3599 
3600           for (i = 0; groups[i] > 0; i++) {
3601                     if (groups[i] == group)
3602                               return 1;
3603           }
3604 
3605           return 0;
3606 }
3607 
3608 
owe_process_assoc_req(struct hostapd_data * hapd,struct sta_info * sta,const u8 * owe_dh,u8 owe_dh_len)3609 static u16 owe_process_assoc_req(struct hostapd_data *hapd,
3610                                          struct sta_info *sta, const u8 *owe_dh,
3611                                          u8 owe_dh_len)
3612 {
3613           struct wpabuf *secret, *pub, *hkey;
3614           int res;
3615           u8 prk[SHA512_MAC_LEN], pmkid[SHA512_MAC_LEN];
3616           const char *info = "OWE Key Generation";
3617           const u8 *addr[2];
3618           size_t len[2];
3619           u16 group;
3620           size_t hash_len, prime_len;
3621 
3622           if (wpa_auth_sta_get_pmksa(sta->wpa_sm)) {
3623                     wpa_printf(MSG_DEBUG, "OWE: Using PMKSA caching");
3624                     return WLAN_STATUS_SUCCESS;
3625           }
3626 
3627           group = WPA_GET_LE16(owe_dh);
3628           if (!owe_group_supported(hapd, group)) {
3629                     wpa_printf(MSG_DEBUG, "OWE: Unsupported DH group %u", group);
3630                     return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
3631           }
3632           if (group == 19)
3633                     prime_len = 32;
3634           else if (group == 20)
3635                     prime_len = 48;
3636           else if (group == 21)
3637                     prime_len = 66;
3638           else
3639                     return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
3640 
3641           if (sta->owe_group == group && sta->owe_ecdh) {
3642                     /* This is a workaround for mac80211 behavior of retransmitting
3643                      * the Association Request frames multiple times if the link
3644                      * layer retries (i.e., seq# remains same) fail. The mac80211
3645                      * initiated retransmission will use a different seq# and as
3646                      * such, will go through duplicate detection. If we were to
3647                      * change our DH key for that attempt, there would be two
3648                      * different DH shared secrets and the STA would likely select
3649                      * the wrong one. */
3650                     wpa_printf(MSG_DEBUG,
3651                                  "OWE: Try to reuse own previous DH key since the STA tried to go through OWE association again");
3652           } else {
3653                     crypto_ecdh_deinit(sta->owe_ecdh);
3654                     sta->owe_ecdh = crypto_ecdh_init(group);
3655           }
3656           if (!sta->owe_ecdh)
3657                     return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
3658           sta->owe_group = group;
3659 
3660           secret = crypto_ecdh_set_peerkey(sta->owe_ecdh, 0, owe_dh + 2,
3661                                                    owe_dh_len - 2);
3662           secret = wpabuf_zeropad(secret, prime_len);
3663           if (!secret) {
3664                     wpa_printf(MSG_DEBUG, "OWE: Invalid peer DH public key");
3665                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
3666           }
3667           wpa_hexdump_buf_key(MSG_DEBUG, "OWE: DH shared secret", secret);
3668 
3669           /* prk = HKDF-extract(C | A | group, z) */
3670 
3671           pub = crypto_ecdh_get_pubkey(sta->owe_ecdh, 0);
3672           if (!pub) {
3673                     wpabuf_clear_free(secret);
3674                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
3675           }
3676 
3677           /* PMKID = Truncate-128(Hash(C | A)) */
3678           addr[0] = owe_dh + 2;
3679           len[0] = owe_dh_len - 2;
3680           addr[1] = wpabuf_head(pub);
3681           len[1] = wpabuf_len(pub);
3682           if (group == 19) {
3683                     res = sha256_vector(2, addr, len, pmkid);
3684                     hash_len = SHA256_MAC_LEN;
3685           } else if (group == 20) {
3686                     res = sha384_vector(2, addr, len, pmkid);
3687                     hash_len = SHA384_MAC_LEN;
3688           } else if (group == 21) {
3689                     res = sha512_vector(2, addr, len, pmkid);
3690                     hash_len = SHA512_MAC_LEN;
3691           } else {
3692                     wpabuf_free(pub);
3693                     wpabuf_clear_free(secret);
3694                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
3695           }
3696           pub = wpabuf_zeropad(pub, prime_len);
3697           if (res < 0 || !pub) {
3698                     wpabuf_free(pub);
3699                     wpabuf_clear_free(secret);
3700                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
3701           }
3702 
3703           hkey = wpabuf_alloc(owe_dh_len - 2 + wpabuf_len(pub) + 2);
3704           if (!hkey) {
3705                     wpabuf_free(pub);
3706                     wpabuf_clear_free(secret);
3707                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
3708           }
3709 
3710           wpabuf_put_data(hkey, owe_dh + 2, owe_dh_len - 2); /* C */
3711           wpabuf_put_buf(hkey, pub); /* A */
3712           wpabuf_free(pub);
3713           wpabuf_put_le16(hkey, group); /* group */
3714           if (group == 19)
3715                     res = hmac_sha256(wpabuf_head(hkey), wpabuf_len(hkey),
3716                                           wpabuf_head(secret), wpabuf_len(secret), prk);
3717           else if (group == 20)
3718                     res = hmac_sha384(wpabuf_head(hkey), wpabuf_len(hkey),
3719                                           wpabuf_head(secret), wpabuf_len(secret), prk);
3720           else if (group == 21)
3721                     res = hmac_sha512(wpabuf_head(hkey), wpabuf_len(hkey),
3722                                           wpabuf_head(secret), wpabuf_len(secret), prk);
3723           wpabuf_clear_free(hkey);
3724           wpabuf_clear_free(secret);
3725           if (res < 0)
3726                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
3727 
3728           wpa_hexdump_key(MSG_DEBUG, "OWE: prk", prk, hash_len);
3729 
3730           /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */
3731 
3732           os_free(sta->owe_pmk);
3733           sta->owe_pmk = os_malloc(hash_len);
3734           if (!sta->owe_pmk) {
3735                     os_memset(prk, 0, SHA512_MAC_LEN);
3736                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
3737           }
3738 
3739           if (group == 19)
3740                     res = hmac_sha256_kdf(prk, hash_len, NULL, (const u8 *) info,
3741                                               os_strlen(info), sta->owe_pmk, hash_len);
3742           else if (group == 20)
3743                     res = hmac_sha384_kdf(prk, hash_len, NULL, (const u8 *) info,
3744                                               os_strlen(info), sta->owe_pmk, hash_len);
3745           else if (group == 21)
3746                     res = hmac_sha512_kdf(prk, hash_len, NULL, (const u8 *) info,
3747                                               os_strlen(info), sta->owe_pmk, hash_len);
3748           os_memset(prk, 0, SHA512_MAC_LEN);
3749           if (res < 0) {
3750                     os_free(sta->owe_pmk);
3751                     sta->owe_pmk = NULL;
3752                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
3753           }
3754           sta->owe_pmk_len = hash_len;
3755 
3756           wpa_hexdump_key(MSG_DEBUG, "OWE: PMK", sta->owe_pmk, sta->owe_pmk_len);
3757           wpa_hexdump(MSG_DEBUG, "OWE: PMKID", pmkid, PMKID_LEN);
3758           wpa_auth_pmksa_add2(hapd->wpa_auth, sta->addr, sta->owe_pmk,
3759                                   sta->owe_pmk_len, pmkid, 0, WPA_KEY_MGMT_OWE, NULL);
3760 
3761           return WLAN_STATUS_SUCCESS;
3762 }
3763 
3764 
owe_validate_request(struct hostapd_data * hapd,const u8 * peer,const u8 * rsn_ie,size_t rsn_ie_len,const u8 * owe_dh,size_t owe_dh_len)3765 u16 owe_validate_request(struct hostapd_data *hapd, const u8 *peer,
3766                                const u8 *rsn_ie, size_t rsn_ie_len,
3767                                const u8 *owe_dh, size_t owe_dh_len)
3768 {
3769           struct wpa_ie_data data;
3770           int res;
3771 
3772           if (!rsn_ie || rsn_ie_len < 2) {
3773                     wpa_printf(MSG_DEBUG, "OWE: Invalid RSNE from " MACSTR,
3774                                  MAC2STR(peer));
3775                     return WLAN_STATUS_INVALID_IE;
3776           }
3777           rsn_ie -= 2;
3778           rsn_ie_len += 2;
3779 
3780           res = wpa_parse_wpa_ie_rsn(rsn_ie, rsn_ie_len, &data);
3781           if (res) {
3782                     wpa_printf(MSG_DEBUG, "Failed to parse RSNE from " MACSTR
3783                                  " (res=%d)", MAC2STR(peer), res);
3784                     wpa_hexdump(MSG_DEBUG, "RSNE", rsn_ie, rsn_ie_len);
3785                     return wpa_res_to_status_code(res);
3786           }
3787           if (!(data.key_mgmt & WPA_KEY_MGMT_OWE)) {
3788                     wpa_printf(MSG_DEBUG,
3789                                  "OWE: Unexpected key mgmt 0x%x from " MACSTR,
3790                                  (unsigned int) data.key_mgmt, MAC2STR(peer));
3791                     return WLAN_STATUS_AKMP_NOT_VALID;
3792           }
3793           if (!owe_dh) {
3794                     wpa_printf(MSG_DEBUG,
3795                                  "OWE: No Diffie-Hellman Parameter element from "
3796                                  MACSTR, MAC2STR(peer));
3797                     return WLAN_STATUS_AKMP_NOT_VALID;
3798           }
3799 
3800           return WLAN_STATUS_SUCCESS;
3801 }
3802 
3803 
owe_process_rsn_ie(struct hostapd_data * hapd,struct sta_info * sta,const u8 * rsn_ie,size_t rsn_ie_len,const u8 * owe_dh,size_t owe_dh_len,const u8 * link_addr)3804 u16 owe_process_rsn_ie(struct hostapd_data *hapd,
3805                            struct sta_info *sta,
3806                            const u8 *rsn_ie, size_t rsn_ie_len,
3807                            const u8 *owe_dh, size_t owe_dh_len,
3808                            const u8 *link_addr)
3809 {
3810           u16 status;
3811           u8 *owe_buf, ie[256 * 2];
3812           size_t ie_len = 0;
3813           enum wpa_validate_result res;
3814 
3815           if (!rsn_ie || rsn_ie_len < 2) {
3816                     wpa_printf(MSG_DEBUG, "OWE: No RSNE in (Re)AssocReq");
3817                     status = WLAN_STATUS_INVALID_IE;
3818                     goto end;
3819           }
3820 
3821           if (!sta->wpa_sm)
3822                     sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,   sta->addr,
3823                                                             NULL);
3824           if (!sta->wpa_sm) {
3825                     wpa_printf(MSG_WARNING,
3826                                  "OWE: Failed to initialize WPA state machine");
3827                     status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3828                     goto end;
3829           }
3830 #ifdef CONFIG_IEEE80211BE
3831           if (ap_sta_is_mld(hapd, sta))
3832                     wpa_auth_set_ml_info(sta->wpa_sm,
3833                                              sta->mld_assoc_link_id, &sta->mld_info);
3834 #endif /* CONFIG_IEEE80211BE */
3835           rsn_ie -= 2;
3836           rsn_ie_len += 2;
3837           res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
3838                                           hapd->iface->freq, rsn_ie, rsn_ie_len,
3839                                           NULL, 0, NULL, 0, owe_dh, owe_dh_len, NULL);
3840           status = wpa_res_to_status_code(res);
3841           if (status != WLAN_STATUS_SUCCESS)
3842                     goto end;
3843           status = owe_process_assoc_req(hapd, sta, owe_dh, owe_dh_len);
3844           if (status != WLAN_STATUS_SUCCESS)
3845                     goto end;
3846           owe_buf = wpa_auth_write_assoc_resp_owe(sta->wpa_sm, ie, sizeof(ie),
3847                                                             NULL, 0);
3848           if (!owe_buf) {
3849                     status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3850                     goto end;
3851           }
3852 
3853           if (sta->owe_ecdh) {
3854                     struct wpabuf *pub;
3855 
3856                     pub = crypto_ecdh_get_pubkey(sta->owe_ecdh, 0);
3857                     if (!pub) {
3858                               status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3859                               goto end;
3860                     }
3861 
3862                     /* OWE Diffie-Hellman Parameter element */
3863                     *owe_buf++ = WLAN_EID_EXTENSION; /* Element ID */
3864                     *owe_buf++ = 1 + 2 + wpabuf_len(pub); /* Length */
3865                     *owe_buf++ = WLAN_EID_EXT_OWE_DH_PARAM; /* Element ID Extension
3866                                                                        */
3867                     WPA_PUT_LE16(owe_buf, sta->owe_group);
3868                     owe_buf += 2;
3869                     os_memcpy(owe_buf, wpabuf_head(pub), wpabuf_len(pub));
3870                     owe_buf += wpabuf_len(pub);
3871                     wpabuf_free(pub);
3872                     sta->external_dh_updated = 1;
3873           }
3874           ie_len = owe_buf - ie;
3875 
3876 end:
3877           wpa_printf(MSG_DEBUG, "OWE: Update status %d, ie len %d for peer "
3878                                     MACSTR, status, (unsigned int) ie_len,
3879                                     MAC2STR(link_addr ? link_addr : sta->addr));
3880           hostapd_drv_update_dh_ie(hapd, link_addr ? link_addr : sta->addr,
3881                                          status,
3882                                          status == WLAN_STATUS_SUCCESS ? ie : NULL,
3883                                          ie_len);
3884 
3885           return status;
3886 }
3887 
3888 #endif /* CONFIG_OWE */
3889 
3890 
check_sa_query(struct hostapd_data * hapd,struct sta_info * sta,int reassoc)3891 static bool check_sa_query(struct hostapd_data *hapd, struct sta_info *sta,
3892                                  int reassoc)
3893 {
3894           if ((sta->flags &
3895                (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED)) !=
3896               (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED))
3897                     return false;
3898 
3899           if (!sta->sa_query_timed_out && sta->sa_query_count > 0)
3900                     ap_check_sa_query_timeout(hapd, sta);
3901 
3902           if (!sta->sa_query_timed_out &&
3903               (!reassoc || sta->auth_alg != WLAN_AUTH_FT)) {
3904                     /*
3905                      * STA has already been associated with MFP and SA Query timeout
3906                      * has not been reached. Reject the association attempt
3907                      * temporarily and start SA Query, if one is not pending.
3908                      */
3909                     if (sta->sa_query_count == 0)
3910                               ap_sta_start_sa_query(hapd, sta);
3911 
3912                     return true;
3913           }
3914 
3915           return false;
3916 }
3917 
3918 
__check_assoc_ies(struct hostapd_data * hapd,struct sta_info * sta,const u8 * ies,size_t ies_len,struct ieee802_11_elems * elems,int reassoc,bool link)3919 static int __check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
3920                                    const u8 *ies, size_t ies_len,
3921                                    struct ieee802_11_elems *elems, int reassoc,
3922                                    bool link)
3923 {
3924           int resp;
3925           const u8 *wpa_ie;
3926           size_t wpa_ie_len;
3927           const u8 *p2p_dev_addr = NULL;
3928           struct hostapd_data *assoc_hapd;
3929           struct sta_info *assoc_sta = NULL;
3930 
3931           resp = check_ssid(hapd, sta, elems->ssid, elems->ssid_len);
3932           if (resp != WLAN_STATUS_SUCCESS)
3933                     return resp;
3934           resp = check_wmm(hapd, sta, elems->wmm, elems->wmm_len);
3935           if (resp != WLAN_STATUS_SUCCESS)
3936                     return resp;
3937           resp = check_ext_capab(hapd, sta, elems->ext_capab,
3938                                      elems->ext_capab_len);
3939           if (resp != WLAN_STATUS_SUCCESS)
3940                     return resp;
3941           resp = copy_supp_rates(hapd, sta, elems);
3942           if (resp != WLAN_STATUS_SUCCESS)
3943                     return resp;
3944 
3945           resp = check_multi_ap(hapd, sta, elems->multi_ap, elems->multi_ap_len);
3946           if (resp != WLAN_STATUS_SUCCESS)
3947                     return resp;
3948 
3949           resp = copy_sta_ht_capab(hapd, sta, elems->ht_capabilities);
3950           if (resp != WLAN_STATUS_SUCCESS)
3951                     return resp;
3952           if (hapd->iconf->ieee80211n && hapd->iconf->require_ht &&
3953               !(sta->flags & WLAN_STA_HT)) {
3954                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3955                                      HOSTAPD_LEVEL_INFO, "Station does not support "
3956                                      "mandatory HT PHY - reject association");
3957                     return WLAN_STATUS_ASSOC_DENIED_NO_HT;
3958           }
3959 
3960 #ifdef CONFIG_IEEE80211AC
3961           if (hapd->iconf->ieee80211ac) {
3962                     resp = copy_sta_vht_capab(hapd, sta, elems->vht_capabilities);
3963                     if (resp != WLAN_STATUS_SUCCESS)
3964                               return resp;
3965 
3966                     resp = set_sta_vht_opmode(hapd, sta, elems->opmode_notif);
3967                     if (resp != WLAN_STATUS_SUCCESS)
3968                               return resp;
3969           }
3970 
3971           if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht &&
3972               !(sta->flags & WLAN_STA_VHT)) {
3973                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3974                                      HOSTAPD_LEVEL_INFO, "Station does not support "
3975                                      "mandatory VHT PHY - reject association");
3976                     return WLAN_STATUS_ASSOC_DENIED_NO_VHT;
3977           }
3978 
3979           if (hapd->conf->vendor_vht && !elems->vht_capabilities) {
3980                     resp = copy_sta_vendor_vht(hapd, sta, elems->vendor_vht,
3981                                                      elems->vendor_vht_len);
3982                     if (resp != WLAN_STATUS_SUCCESS)
3983                               return resp;
3984           }
3985 #endif /* CONFIG_IEEE80211AC */
3986 #ifdef CONFIG_IEEE80211AX
3987           if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
3988                     resp = copy_sta_he_capab(hapd, sta, IEEE80211_MODE_AP,
3989                                                    elems->he_capabilities,
3990                                                    elems->he_capabilities_len);
3991                     if (resp != WLAN_STATUS_SUCCESS)
3992                               return resp;
3993 
3994                     if (hapd->iconf->require_he && !(sta->flags & WLAN_STA_HE)) {
3995                               hostapd_logger(hapd, sta->addr,
3996                                                HOSTAPD_MODULE_IEEE80211,
3997                                                HOSTAPD_LEVEL_INFO,
3998                                                "Station does not support mandatory HE PHY - reject association");
3999                               return WLAN_STATUS_DENIED_HE_NOT_SUPPORTED;
4000                     }
4001 
4002                     if (is_6ghz_op_class(hapd->iconf->op_class)) {
4003                               if (!(sta->flags & WLAN_STA_HE)) {
4004                                         hostapd_logger(hapd, sta->addr,
4005                                                          HOSTAPD_MODULE_IEEE80211,
4006                                                          HOSTAPD_LEVEL_INFO,
4007                                                          "Station does not support mandatory HE PHY - reject association");
4008                                         return WLAN_STATUS_DENIED_HE_NOT_SUPPORTED;
4009                               }
4010                               resp = copy_sta_he_6ghz_capab(hapd, sta,
4011                                                                   elems->he_6ghz_band_cap);
4012                               if (resp != WLAN_STATUS_SUCCESS)
4013                                         return resp;
4014                     }
4015           }
4016 #endif /* CONFIG_IEEE80211AX */
4017 #ifdef CONFIG_IEEE80211BE
4018           if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
4019                     resp = copy_sta_eht_capab(hapd, sta, IEEE80211_MODE_AP,
4020                                                     elems->he_capabilities,
4021                                                     elems->he_capabilities_len,
4022                                                     elems->eht_capabilities,
4023                                                     elems->eht_capabilities_len);
4024                     if (resp != WLAN_STATUS_SUCCESS)
4025                               return resp;
4026 
4027                     if (!link) {
4028                               resp = hostapd_process_ml_assoc_req(hapd, elems, sta);
4029                               if (resp != WLAN_STATUS_SUCCESS)
4030                                         return resp;
4031                     }
4032           }
4033 #endif /* CONFIG_IEEE80211BE */
4034 
4035 #ifdef CONFIG_P2P
4036           if (elems->p2p && ies && ies_len) {
4037                     wpabuf_free(sta->p2p_ie);
4038                     sta->p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
4039                                                                         P2P_IE_VENDOR_TYPE);
4040                     if (sta->p2p_ie)
4041                               p2p_dev_addr = p2p_get_go_dev_addr(sta->p2p_ie);
4042           } else {
4043                     wpabuf_free(sta->p2p_ie);
4044                     sta->p2p_ie = NULL;
4045           }
4046 #endif /* CONFIG_P2P */
4047 
4048           if ((hapd->conf->wpa & WPA_PROTO_RSN) && elems->rsn_ie) {
4049                     wpa_ie = elems->rsn_ie;
4050                     wpa_ie_len = elems->rsn_ie_len;
4051           } else if ((hapd->conf->wpa & WPA_PROTO_WPA) &&
4052                        elems->wpa_ie) {
4053                     wpa_ie = elems->wpa_ie;
4054                     wpa_ie_len = elems->wpa_ie_len;
4055           } else {
4056                     wpa_ie = NULL;
4057                     wpa_ie_len = 0;
4058           }
4059 
4060 #ifdef CONFIG_WPS
4061           sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
4062           if (hapd->conf->wps_state && elems->wps_ie && ies && ies_len) {
4063                     wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)Association "
4064                                  "Request - assume WPS is used");
4065                     sta->flags |= WLAN_STA_WPS;
4066                     wpabuf_free(sta->wps_ie);
4067                     sta->wps_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
4068                                                                         WPS_IE_VENDOR_TYPE);
4069                     if (sta->wps_ie && wps_is_20(sta->wps_ie)) {
4070                               wpa_printf(MSG_DEBUG, "WPS: STA supports WPS 2.0");
4071                               sta->flags |= WLAN_STA_WPS2;
4072                     }
4073                     wpa_ie = NULL;
4074                     wpa_ie_len = 0;
4075                     if (sta->wps_ie && wps_validate_assoc_req(sta->wps_ie) < 0) {
4076                               wpa_printf(MSG_DEBUG, "WPS: Invalid WPS IE in "
4077                                            "(Re)Association Request - reject");
4078                               return WLAN_STATUS_INVALID_IE;
4079                     }
4080           } else if (hapd->conf->wps_state && wpa_ie == NULL) {
4081                     wpa_printf(MSG_DEBUG, "STA did not include WPA/RSN IE in "
4082                                  "(Re)Association Request - possible WPS use");
4083                     sta->flags |= WLAN_STA_MAYBE_WPS;
4084           } else
4085 #endif /* CONFIG_WPS */
4086           if (hapd->conf->wpa && wpa_ie == NULL) {
4087                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4088                                      HOSTAPD_LEVEL_INFO,
4089                                      "No WPA/RSN IE in association request");
4090                     return WLAN_STATUS_INVALID_IE;
4091           }
4092 
4093           if (hapd->conf->wpa && wpa_ie) {
4094                     enum wpa_validate_result res;
4095 #ifdef CONFIG_IEEE80211BE
4096                     struct mld_info *info = &sta->mld_info;
4097                     bool init = !sta->wpa_sm;
4098 #endif /* CONFIG_IEEE80211BE */
4099 
4100                     wpa_ie -= 2;
4101                     wpa_ie_len += 2;
4102 
4103                     if (!sta->wpa_sm) {
4104                               if (!link)
4105                                         assoc_sta = hostapd_ml_get_assoc_sta(
4106                                                   hapd, sta, &assoc_hapd);
4107 
4108                               sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
4109                                                                       sta->addr,
4110                                                                       p2p_dev_addr);
4111 
4112                               if (!sta->wpa_sm) {
4113                                         wpa_printf(MSG_WARNING,
4114                                                      "Failed to initialize RSN state machine");
4115                                         return WLAN_STATUS_UNSPECIFIED_FAILURE;
4116                               }
4117                     }
4118 
4119 #ifdef CONFIG_IEEE80211BE
4120                     if (ap_sta_is_mld(hapd, sta)) {
4121                               wpa_printf(MSG_DEBUG,
4122                                            "MLD: %s ML info in RSN Authenticator",
4123                                            init ? "Set" : "Reset");
4124                               wpa_auth_set_ml_info(sta->wpa_sm,
4125                                                        sta->mld_assoc_link_id,
4126                                                        info);
4127                     }
4128 #endif /* CONFIG_IEEE80211BE */
4129 
4130                     wpa_auth_set_auth_alg(sta->wpa_sm, sta->auth_alg);
4131                     res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
4132                                                     hapd->iface->freq,
4133                                                     wpa_ie, wpa_ie_len,
4134                                                     elems->rsnxe ? elems->rsnxe - 2 :
4135                                                     NULL,
4136                                                     elems->rsnxe ? elems->rsnxe_len + 2 :
4137                                                     0,
4138                                                     elems->mdie, elems->mdie_len,
4139                                                     elems->owe_dh, elems->owe_dh_len,
4140                                                     assoc_sta ? assoc_sta->wpa_sm : NULL);
4141                     resp = wpa_res_to_status_code(res);
4142                     if (resp != WLAN_STATUS_SUCCESS)
4143                               return resp;
4144 
4145                     if (wpa_auth_uses_mfp(sta->wpa_sm))
4146                               sta->flags |= WLAN_STA_MFP;
4147                     else
4148                               sta->flags &= ~WLAN_STA_MFP;
4149 
4150 #ifdef CONFIG_IEEE80211R_AP
4151                     if (sta->auth_alg == WLAN_AUTH_FT) {
4152                               if (!reassoc) {
4153                                         wpa_printf(MSG_DEBUG, "FT: " MACSTR " tried "
4154                                                      "to use association (not "
4155                                                      "re-association) with FT auth_alg",
4156                                                      MAC2STR(sta->addr));
4157                                         return WLAN_STATUS_UNSPECIFIED_FAILURE;
4158                               }
4159 
4160                               resp = wpa_ft_validate_reassoc(sta->wpa_sm, ies,
4161                                                                    ies_len);
4162                               if (resp != WLAN_STATUS_SUCCESS)
4163                                         return resp;
4164                     }
4165 #endif /* CONFIG_IEEE80211R_AP */
4166 
4167                     if (link)
4168                               goto skip_sae_owe;
4169 #ifdef CONFIG_SAE
4170                     if (wpa_auth_uses_sae(sta->wpa_sm) && sta->sae &&
4171                         sta->sae->state == SAE_ACCEPTED)
4172                               wpa_auth_add_sae_pmkid(sta->wpa_sm, sta->sae->pmkid);
4173 
4174                     if (wpa_auth_uses_sae(sta->wpa_sm) &&
4175                         sta->auth_alg == WLAN_AUTH_OPEN) {
4176                               struct rsn_pmksa_cache_entry *sa;
4177                               sa = wpa_auth_sta_get_pmksa(sta->wpa_sm);
4178                               if (!sa || !wpa_key_mgmt_sae(sa->akmp)) {
4179                                         wpa_printf(MSG_DEBUG,
4180                                                      "SAE: No PMKSA cache entry found for "
4181                                                      MACSTR, MAC2STR(sta->addr));
4182                                         return WLAN_STATUS_INVALID_PMKID;
4183                               }
4184                               wpa_printf(MSG_DEBUG, "SAE: " MACSTR
4185                                            " using PMKSA caching", MAC2STR(sta->addr));
4186                     } else if (wpa_auth_uses_sae(sta->wpa_sm) &&
4187                                  sta->auth_alg != WLAN_AUTH_SAE &&
4188                                  !(sta->auth_alg == WLAN_AUTH_FT &&
4189                                    wpa_auth_uses_ft_sae(sta->wpa_sm))) {
4190                               wpa_printf(MSG_DEBUG, "SAE: " MACSTR " tried to use "
4191                                            "SAE AKM after non-SAE auth_alg %u",
4192                                            MAC2STR(sta->addr), sta->auth_alg);
4193                               return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
4194                     }
4195 
4196                     if (hapd->conf->sae_pwe == SAE_PWE_BOTH &&
4197                         sta->auth_alg == WLAN_AUTH_SAE &&
4198                         sta->sae && !sta->sae->h2e &&
4199                         ieee802_11_rsnx_capab_len(elems->rsnxe, elems->rsnxe_len,
4200                                                         WLAN_RSNX_CAPAB_SAE_H2E)) {
4201                               wpa_printf(MSG_INFO, "SAE: " MACSTR
4202                                            " indicates support for SAE H2E, but did not use it",
4203                                            MAC2STR(sta->addr));
4204                               return WLAN_STATUS_UNSPECIFIED_FAILURE;
4205                     }
4206 #endif /* CONFIG_SAE */
4207 
4208 #ifdef CONFIG_OWE
4209                     if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
4210                         wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_OWE &&
4211                         elems->owe_dh) {
4212                               resp = owe_process_assoc_req(hapd, sta, elems->owe_dh,
4213                                                                  elems->owe_dh_len);
4214                               if (resp != WLAN_STATUS_SUCCESS)
4215                                         return resp;
4216                     }
4217 #endif /* CONFIG_OWE */
4218           skip_sae_owe:
4219 
4220 #ifdef CONFIG_DPP2
4221                     dpp_pfs_free(sta->dpp_pfs);
4222                     sta->dpp_pfs = NULL;
4223 
4224                     if (DPP_VERSION > 1 &&
4225                         (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) &&
4226                         hapd->conf->dpp_netaccesskey && sta->wpa_sm &&
4227                         wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_DPP &&
4228                         elems->owe_dh) {
4229                               sta->dpp_pfs = dpp_pfs_init(
4230                                         wpabuf_head(hapd->conf->dpp_netaccesskey),
4231                                         wpabuf_len(hapd->conf->dpp_netaccesskey));
4232                               if (!sta->dpp_pfs) {
4233                                         wpa_printf(MSG_DEBUG,
4234                                                      "DPP: Could not initialize PFS");
4235                                         /* Try to continue without PFS */
4236                                         goto pfs_fail;
4237                               }
4238 
4239                               if (dpp_pfs_process(sta->dpp_pfs, elems->owe_dh,
4240                                                       elems->owe_dh_len) < 0) {
4241                                         dpp_pfs_free(sta->dpp_pfs);
4242                                         sta->dpp_pfs = NULL;
4243                                         return WLAN_STATUS_UNSPECIFIED_FAILURE;
4244                               }
4245                     }
4246 
4247                     wpa_auth_set_dpp_z(sta->wpa_sm, sta->dpp_pfs ?
4248                                            sta->dpp_pfs->secret : NULL);
4249           pfs_fail:
4250 #endif /* CONFIG_DPP2 */
4251 
4252                     if ((sta->flags & (WLAN_STA_HT | WLAN_STA_VHT)) &&
4253                         wpa_auth_get_pairwise(sta->wpa_sm) == WPA_CIPHER_TKIP) {
4254                               hostapd_logger(hapd, sta->addr,
4255                                                HOSTAPD_MODULE_IEEE80211,
4256                                                HOSTAPD_LEVEL_INFO,
4257                                                "Station tried to use TKIP with HT "
4258                                                "association");
4259                               return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
4260                     }
4261 
4262                     wpa_auth_set_ssid_protection(
4263                               sta->wpa_sm,
4264                               hapd->conf->ssid_protection &&
4265                               ieee802_11_rsnx_capab_len(
4266                                         elems->rsnxe, elems->rsnxe_len,
4267                                         WLAN_RSNX_CAPAB_SSID_PROTECTION));
4268 #ifdef CONFIG_HS20
4269           } else if (hapd->conf->osen) {
4270                     if (!elems->osen) {
4271                               hostapd_logger(
4272                                         hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4273                                         HOSTAPD_LEVEL_INFO,
4274                                         "No HS 2.0 OSEN element in association request");
4275                               return WLAN_STATUS_INVALID_IE;
4276                     }
4277 
4278                     wpa_printf(MSG_DEBUG, "HS 2.0: OSEN association");
4279                     if (sta->wpa_sm == NULL)
4280                               sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
4281                                                                       sta->addr, NULL);
4282                     if (sta->wpa_sm == NULL) {
4283                               wpa_printf(MSG_WARNING, "Failed to initialize WPA "
4284                                            "state machine");
4285                               return WLAN_STATUS_UNSPECIFIED_FAILURE;
4286                     }
4287                     if (wpa_validate_osen(hapd->wpa_auth, sta->wpa_sm,
4288                                               elems->osen - 2, elems->osen_len + 2) < 0)
4289                               return WLAN_STATUS_INVALID_IE;
4290 #endif /* CONFIG_HS20 */
4291           } else
4292                     wpa_auth_sta_no_wpa(sta->wpa_sm);
4293 
4294 #ifdef CONFIG_P2P
4295           p2p_group_notif_assoc(hapd->p2p_group, sta->addr, ies, ies_len);
4296 #endif /* CONFIG_P2P */
4297 
4298 #ifdef CONFIG_HS20
4299           wpabuf_free(sta->hs20_ie);
4300           if (elems->hs20 && elems->hs20_len > 4) {
4301                     int release;
4302 
4303                     sta->hs20_ie = wpabuf_alloc_copy(elems->hs20 + 4,
4304                                                              elems->hs20_len - 4);
4305                     release = ((elems->hs20[4] >> 4) & 0x0f) + 1;
4306                     if (release >= 2 && !wpa_auth_uses_mfp(sta->wpa_sm) &&
4307                         hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
4308                               wpa_printf(MSG_DEBUG,
4309                                            "HS 2.0: PMF not negotiated by release %d station "
4310                                            MACSTR, release, MAC2STR(sta->addr));
4311                               return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
4312                     }
4313           } else {
4314                     sta->hs20_ie = NULL;
4315           }
4316 
4317           wpabuf_free(sta->roaming_consortium);
4318           if (elems->roaming_cons_sel)
4319                     sta->roaming_consortium = wpabuf_alloc_copy(
4320                               elems->roaming_cons_sel + 4,
4321                               elems->roaming_cons_sel_len - 4);
4322           else
4323                     sta->roaming_consortium = NULL;
4324 #endif /* CONFIG_HS20 */
4325 
4326 #ifdef CONFIG_FST
4327           wpabuf_free(sta->mb_ies);
4328           if (hapd->iface->fst)
4329                     sta->mb_ies = mb_ies_by_info(&elems->mb_ies);
4330           else
4331                     sta->mb_ies = NULL;
4332 #endif /* CONFIG_FST */
4333 
4334 #ifdef CONFIG_MBO
4335           mbo_ap_check_sta_assoc(hapd, sta, elems);
4336 
4337           if (hapd->conf->mbo_enabled && (hapd->conf->wpa & 2) &&
4338               elems->mbo && sta->cell_capa && !(sta->flags & WLAN_STA_MFP) &&
4339               hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
4340                     wpa_printf(MSG_INFO,
4341                                  "MBO: Reject WPA2 association without PMF");
4342                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
4343           }
4344 #endif /* CONFIG_MBO */
4345 
4346 #if defined(CONFIG_FILS) && defined(CONFIG_OCV)
4347           if (wpa_auth_uses_ocv(sta->wpa_sm) &&
4348               (sta->auth_alg == WLAN_AUTH_FILS_SK ||
4349                sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
4350                sta->auth_alg == WLAN_AUTH_FILS_PK)) {
4351                     struct wpa_channel_info ci;
4352                     int tx_chanwidth;
4353                     int tx_seg1_idx;
4354                     enum oci_verify_result res;
4355 
4356                     if (hostapd_drv_channel_info(hapd, &ci) != 0) {
4357                               wpa_printf(MSG_WARNING,
4358                                            "Failed to get channel info to validate received OCI in FILS (Re)Association Request frame");
4359                               return WLAN_STATUS_UNSPECIFIED_FAILURE;
4360                     }
4361 
4362                     if (get_sta_tx_parameters(sta->wpa_sm,
4363                                                     channel_width_to_int(ci.chanwidth),
4364                                                     ci.seg1_idx, &tx_chanwidth,
4365                                                     &tx_seg1_idx) < 0)
4366                               return WLAN_STATUS_UNSPECIFIED_FAILURE;
4367 
4368                     res = ocv_verify_tx_params(elems->oci, elems->oci_len, &ci,
4369                                                      tx_chanwidth, tx_seg1_idx);
4370                     if (wpa_auth_uses_ocv(sta->wpa_sm) == 2 &&
4371                         res == OCI_NOT_FOUND) {
4372                               /* Work around misbehaving STAs */
4373                               wpa_printf(MSG_INFO,
4374                                            "FILS: Disable OCV with a STA that does not send OCI");
4375                               wpa_auth_set_ocv(sta->wpa_sm, 0);
4376                     } else if (res != OCI_SUCCESS) {
4377                               wpa_printf(MSG_WARNING, "FILS: OCV failed: %s",
4378                                            ocv_errorstr);
4379                               wpa_msg(hapd->msg_ctx, MSG_INFO, OCV_FAILURE "addr="
4380                                         MACSTR " frame=fils-reassoc-req error=%s",
4381                                         MAC2STR(sta->addr), ocv_errorstr);
4382                               return WLAN_STATUS_UNSPECIFIED_FAILURE;
4383                     }
4384           }
4385 #endif /* CONFIG_FILS && CONFIG_OCV */
4386 
4387           ap_copy_sta_supp_op_classes(sta, elems->supp_op_classes,
4388                                             elems->supp_op_classes_len);
4389 
4390           if ((sta->capability & WLAN_CAPABILITY_RADIO_MEASUREMENT) &&
4391               elems->rrm_enabled &&
4392               elems->rrm_enabled_len >= sizeof(sta->rrm_enabled_capa))
4393                     os_memcpy(sta->rrm_enabled_capa, elems->rrm_enabled,
4394                                 sizeof(sta->rrm_enabled_capa));
4395 
4396           if (elems->power_capab) {
4397                     sta->min_tx_power = elems->power_capab[0];
4398                     sta->max_tx_power = elems->power_capab[1];
4399                     sta->power_capab = 1;
4400           } else {
4401                     sta->power_capab = 0;
4402           }
4403 
4404           if (elems->bss_max_idle_period &&
4405               hapd->conf->max_acceptable_idle_period) {
4406                     u16 req;
4407 
4408                     req = WPA_GET_LE16(elems->bss_max_idle_period);
4409                     if (req <= hapd->conf->max_acceptable_idle_period)
4410                               sta->max_idle_period = req;
4411                     else if (hapd->conf->max_acceptable_idle_period >
4412                                hapd->conf->ap_max_inactivity)
4413                               sta->max_idle_period =
4414                                         hapd->conf->max_acceptable_idle_period;
4415           }
4416 
4417           return WLAN_STATUS_SUCCESS;
4418 }
4419 
4420 
check_assoc_ies(struct hostapd_data * hapd,struct sta_info * sta,const u8 * ies,size_t ies_len,int reassoc)4421 static int check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
4422                                  const u8 *ies, size_t ies_len, int reassoc)
4423 {
4424           struct ieee802_11_elems elems;
4425 
4426           if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) {
4427                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4428                                      HOSTAPD_LEVEL_INFO,
4429                                      "Station sent an invalid association request");
4430                     return WLAN_STATUS_UNSPECIFIED_FAILURE;
4431           }
4432 
4433           return __check_assoc_ies(hapd, sta, ies, ies_len, &elems, reassoc,
4434                                          false);
4435 }
4436 
4437 
4438 #ifdef CONFIG_IEEE80211BE
4439 
ieee80211_ml_build_assoc_resp(struct hostapd_data * hapd,struct mld_link_info * link)4440 static void ieee80211_ml_build_assoc_resp(struct hostapd_data *hapd,
4441                                                     struct mld_link_info *link)
4442 {
4443           u8 buf[EHT_ML_MAX_STA_PROF_LEN];
4444           u8 *p = buf;
4445           size_t buflen = sizeof(buf);
4446 
4447           /* Capability Info */
4448           WPA_PUT_LE16(p, hostapd_own_capab_info(hapd));
4449           p += 2;
4450 
4451           /* Status Code */
4452           WPA_PUT_LE16(p, link->status);
4453           p += 2;
4454 
4455           if (link->status != WLAN_STATUS_SUCCESS)
4456                     goto out;
4457 
4458           /* AID is not included */
4459           p = hostapd_eid_supp_rates(hapd, p);
4460           p = hostapd_eid_ext_supp_rates(hapd, p);
4461           p = hostapd_eid_rm_enabled_capab(hapd, p, buf + buflen - p);
4462           p = hostapd_eid_ht_capabilities(hapd, p);
4463           p = hostapd_eid_ht_operation(hapd, p);
4464 
4465           if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
4466                     p = hostapd_eid_vht_capabilities(hapd, p, 0);
4467                     p = hostapd_eid_vht_operation(hapd, p);
4468           }
4469 
4470           if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
4471                     p = hostapd_eid_he_capab(hapd, p, IEEE80211_MODE_AP);
4472                     p = hostapd_eid_he_operation(hapd, p);
4473                     p = hostapd_eid_spatial_reuse(hapd, p);
4474                     p = hostapd_eid_he_mu_edca_parameter_set(hapd, p);
4475                     p = hostapd_eid_he_6ghz_band_cap(hapd, p);
4476                     if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
4477                               p = hostapd_eid_eht_capab(hapd, p, IEEE80211_MODE_AP);
4478                               p = hostapd_eid_eht_operation(hapd, p);
4479                     }
4480           }
4481 
4482           p = hostapd_eid_ext_capab(hapd, p, false);
4483           p = hostapd_eid_mbo(hapd, p, buf + buflen - p);
4484           p = hostapd_eid_wmm(hapd, p);
4485 
4486           if (hapd->conf->assocresp_elements &&
4487               (size_t) (buf + buflen - p) >=
4488               wpabuf_len(hapd->conf->assocresp_elements)) {
4489                     os_memcpy(p, wpabuf_head(hapd->conf->assocresp_elements),
4490                                 wpabuf_len(hapd->conf->assocresp_elements));
4491                     p += wpabuf_len(hapd->conf->assocresp_elements);
4492           }
4493 
4494 out:
4495           os_free(link->resp_sta_profile);
4496           link->resp_sta_profile = os_memdup(buf, p - buf);
4497           link->resp_sta_profile_len = link->resp_sta_profile ? p - buf : 0;
4498 }
4499 
4500 
ieee80211_ml_process_link(struct hostapd_data * hapd,struct sta_info * origin_sta,struct mld_link_info * link,const u8 * ies,size_t ies_len,bool reassoc,bool offload)4501 static int ieee80211_ml_process_link(struct hostapd_data *hapd,
4502                                              struct sta_info *origin_sta,
4503                                              struct mld_link_info *link,
4504                                              const u8 *ies, size_t ies_len,
4505                                              bool reassoc, bool offload)
4506 {
4507           struct ieee802_11_elems elems;
4508           struct wpabuf *mlbuf = NULL;
4509           struct sta_info *sta = NULL;
4510           u16 status = WLAN_STATUS_SUCCESS;
4511           int i;
4512 
4513           wpa_printf(MSG_DEBUG, "MLD: link: link_id=%u, peer=" MACSTR,
4514                        hapd->mld_link_id, MAC2STR(link->peer_addr));
4515 
4516           if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) {
4517                     wpa_printf(MSG_DEBUG, "MLD: link: Element parsing failed");
4518                     status = WLAN_STATUS_UNSPECIFIED_FAILURE;
4519                     goto out;
4520           }
4521 
4522           sta = ap_get_sta(hapd, origin_sta->addr);
4523           if (sta) {
4524                     wpa_printf(MSG_INFO, "MLD: link: Station already exists");
4525                     status = WLAN_STATUS_UNSPECIFIED_FAILURE;
4526                     sta = NULL;
4527                     goto out;
4528           }
4529 
4530           sta = ap_sta_add(hapd, origin_sta->addr);
4531           if (!sta) {
4532                     wpa_printf(MSG_DEBUG, "MLD: link: ap_sta_add() failed");
4533                     status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
4534                     goto out;
4535           }
4536 
4537           mlbuf = ieee802_11_defrag(elems.basic_mle, elems.basic_mle_len, true);
4538           if (!mlbuf)
4539                     goto out;
4540 
4541           if (ieee802_11_parse_link_assoc_req(ies, ies_len, &elems, mlbuf,
4542                                                       hapd->mld_link_id, true) ==
4543               ParseFailed) {
4544                     wpa_printf(MSG_DEBUG,
4545                                  "MLD: link: Failed to parse association request Multi-Link element");
4546                     status = WLAN_STATUS_UNSPECIFIED_FAILURE;
4547                     goto out;
4548           }
4549 
4550           sta->flags |= origin_sta->flags | WLAN_STA_ASSOC_REQ_OK;
4551           sta->mld_assoc_link_id = origin_sta->mld_assoc_link_id;
4552 
4553           status = __check_assoc_ies(hapd, sta, NULL, 0, &elems, reassoc, true);
4554           if (status != WLAN_STATUS_SUCCESS) {
4555                     wpa_printf(MSG_DEBUG, "MLD: link: Element check failed");
4556                     goto out;
4557           }
4558 
4559           ap_sta_set_mld(sta, true);
4560 
4561           os_memcpy(&sta->mld_info, &origin_sta->mld_info, sizeof(sta->mld_info));
4562           for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
4563                     struct mld_link_info *li = &sta->mld_info.links[i];
4564 
4565                     li->resp_sta_profile = NULL;
4566                     li->resp_sta_profile_len = 0;
4567           }
4568 
4569           if (!offload) {
4570                     /*
4571                      * Get the AID from the station on which the association was
4572                      * performed, and mark it as used.
4573                      */
4574                     sta->aid = origin_sta->aid;
4575                     if (sta->aid == 0) {
4576                               wpa_printf(MSG_DEBUG, "MLD: link: No AID assigned");
4577                               status = WLAN_STATUS_UNSPECIFIED_FAILURE;
4578                               goto out;
4579                     }
4580                     hapd->sta_aid[(sta->aid - 1) / 32] |= BIT((sta->aid - 1) % 32);
4581                     sta->listen_interval = origin_sta->listen_interval;
4582                     if (update_ht_state(hapd, sta) > 0)
4583                               ieee802_11_update_beacons(hapd->iface);
4584           }
4585 
4586           /* Maintain state machine reference on all link STAs, this is needed
4587            * during group rekey handling.
4588            */
4589           wpa_auth_sta_deinit(sta->wpa_sm);
4590           sta->wpa_sm = origin_sta->wpa_sm;
4591 
4592           /*
4593            * Do not initialize the EAPOL state machine.
4594            * TODO: Maybe it is needed?
4595            */
4596           sta->eapol_sm = NULL;
4597 
4598           wpa_printf(MSG_DEBUG, "MLD: link=%u, association OK (aid=%u)",
4599                        hapd->mld_link_id, sta->aid);
4600 
4601           sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC_REQ_OK;
4602 
4603           /* TODO: What other processing is required? */
4604 
4605           if (!offload && add_associated_sta(hapd, sta, reassoc))
4606                     status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
4607 out:
4608           wpabuf_free(mlbuf);
4609           link->status = status;
4610 
4611           if (!offload)
4612                     ieee80211_ml_build_assoc_resp(hapd, link);
4613 
4614           wpa_printf(MSG_DEBUG, "MLD: link: status=%u", status);
4615           if (status != WLAN_STATUS_SUCCESS) {
4616                     if (sta)
4617                               ap_free_sta(hapd, sta);
4618                     return -1;
4619           }
4620 
4621           return 0;
4622 }
4623 
4624 
hostapd_is_mld_ap(struct hostapd_data * hapd)4625 bool hostapd_is_mld_ap(struct hostapd_data *hapd)
4626 {
4627           if (!hapd->conf->mld_ap)
4628                     return false;
4629 
4630           if (!hapd->iface || !hapd->iface->interfaces ||
4631               hapd->iface->interfaces->count <= 1)
4632                     return false;
4633 
4634           return true;
4635 }
4636 
4637 #endif /* CONFIG_IEEE80211BE */
4638 
4639 
hostapd_process_assoc_ml_info(struct hostapd_data * hapd,struct sta_info * sta,const u8 * ies,size_t ies_len,bool reassoc,int tx_link_status,bool offload)4640 int hostapd_process_assoc_ml_info(struct hostapd_data *hapd,
4641                                           struct sta_info *sta,
4642                                           const u8 *ies, size_t ies_len,
4643                                           bool reassoc, int tx_link_status,
4644                                           bool offload)
4645 {
4646 #ifdef CONFIG_IEEE80211BE
4647           unsigned int i;
4648 
4649           if (!hostapd_is_mld_ap(hapd))
4650                     return 0;
4651 
4652           for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
4653                     struct hostapd_data *bss = NULL;
4654                     struct mld_link_info *link = &sta->mld_info.links[i];
4655                     bool link_bss_found = false;
4656 
4657                     if (!link->valid || i == sta->mld_assoc_link_id)
4658                               continue;
4659 
4660                     for_each_mld_link(bss, hapd) {
4661                               if (bss == hapd)
4662                                         continue;
4663 
4664                               if (bss->mld_link_id != i)
4665                                         continue;
4666 
4667                               link_bss_found = true;
4668                               break;
4669                     }
4670 
4671                     if (!link_bss_found || TEST_FAIL()) {
4672                               wpa_printf(MSG_DEBUG,
4673                                            "MLD: No link match for link_id=%u", i);
4674 
4675                               link->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
4676                               if (!offload)
4677                                         ieee80211_ml_build_assoc_resp(hapd, link);
4678                     } else if (tx_link_status != WLAN_STATUS_SUCCESS) {
4679                               /* TX link rejected the connection */
4680                               link->status = WLAN_STATUS_DENIED_TX_LINK_NOT_ACCEPTED;
4681                               if (!offload)
4682                                         ieee80211_ml_build_assoc_resp(hapd, link);
4683                     } else {
4684                               if (ieee80211_ml_process_link(bss, sta, link,
4685                                                                   ies, ies_len, reassoc,
4686                                                                   offload))
4687                                         return -1;
4688                     }
4689           }
4690 #endif /* CONFIG_IEEE80211BE */
4691 
4692           return 0;
4693 }
4694 
4695 
send_deauth(struct hostapd_data * hapd,const u8 * addr,u16 reason_code)4696 static void send_deauth(struct hostapd_data *hapd, const u8 *addr,
4697                               u16 reason_code)
4698 {
4699           int send_len;
4700           struct ieee80211_mgmt reply;
4701 
4702           os_memset(&reply, 0, sizeof(reply));
4703           reply.frame_control =
4704                     IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH);
4705           os_memcpy(reply.da, addr, ETH_ALEN);
4706           os_memcpy(reply.sa, hapd->own_addr, ETH_ALEN);
4707           os_memcpy(reply.bssid, hapd->own_addr, ETH_ALEN);
4708 
4709           send_len = IEEE80211_HDRLEN + sizeof(reply.u.deauth);
4710           reply.u.deauth.reason_code = host_to_le16(reason_code);
4711 
4712           if (hostapd_drv_send_mlme(hapd, &reply, send_len, 0, NULL, 0, 0) < 0)
4713                     wpa_printf(MSG_INFO, "Failed to send deauth: %s",
4714                                  strerror(errno));
4715 }
4716 
4717 
add_associated_sta(struct hostapd_data * hapd,struct sta_info * sta,int reassoc)4718 static int add_associated_sta(struct hostapd_data *hapd,
4719                                     struct sta_info *sta, int reassoc)
4720 {
4721           struct ieee80211_ht_capabilities ht_cap;
4722           struct ieee80211_vht_capabilities vht_cap;
4723           struct ieee80211_he_capabilities he_cap;
4724           struct ieee80211_eht_capabilities eht_cap;
4725           int set = 1;
4726           const u8 *mld_link_addr = NULL;
4727           bool mld_link_sta = false;
4728 
4729 #ifdef CONFIG_IEEE80211BE
4730           if (ap_sta_is_mld(hapd, sta)) {
4731                     u8 mld_link_id = hapd->mld_link_id;
4732 
4733                     mld_link_sta = sta->mld_assoc_link_id != mld_link_id;
4734                     mld_link_addr = sta->mld_info.links[mld_link_id].peer_addr;
4735 
4736                     if (hapd->mld_link_id != sta->mld_assoc_link_id)
4737                               set = 0;
4738           }
4739 #endif /* CONFIG_IEEE80211BE */
4740 
4741           /*
4742            * Remove the STA entry to ensure the STA PS state gets cleared and
4743            * configuration gets updated. This is relevant for cases, such as
4744            * FT-over-the-DS, where a station re-associates back to the same AP but
4745            * skips the authentication flow, or if working with a driver that
4746            * does not support full AP client state.
4747            *
4748            * Skip this if the STA has already completed FT reassociation and the
4749            * TK has been configured since the TX/RX PN must not be reset to 0 for
4750            * the same key.
4751            *
4752            * FT-over-the-DS has a special case where the STA entry (and as such,
4753            * the TK) has not yet been configured to the driver depending on which
4754            * driver interface is used. For that case, allow add-STA operation to
4755            * be used (instead of set-STA). This is needed to allow mac80211-based
4756            * drivers to accept the STA parameter configuration. Since this is
4757            * after a new FT-over-DS exchange, a new TK has been derived, so key
4758            * reinstallation is not a concern for this case.
4759            */
4760           wpa_printf(MSG_DEBUG, "Add associated STA " MACSTR
4761                        " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)",
4762                        MAC2STR(sta->addr), sta->added_unassoc, sta->auth_alg,
4763                        sta->ft_over_ds, reassoc,
4764                        !!(sta->flags & WLAN_STA_AUTHORIZED),
4765                        wpa_auth_sta_ft_tk_already_set(sta->wpa_sm),
4766                        wpa_auth_sta_fils_tk_already_set(sta->wpa_sm));
4767 
4768           if (!mld_link_sta && !sta->added_unassoc &&
4769               (!(sta->flags & WLAN_STA_AUTHORIZED) ||
4770                (reassoc && sta->ft_over_ds && sta->auth_alg == WLAN_AUTH_FT) ||
4771                (!wpa_auth_sta_ft_tk_already_set(sta->wpa_sm) &&
4772                 !wpa_auth_sta_fils_tk_already_set(sta->wpa_sm)))) {
4773                     hostapd_drv_sta_remove(hapd, sta->addr);
4774                     wpa_auth_sm_event(sta->wpa_sm, WPA_DRV_STA_REMOVED);
4775                     set = 0;
4776 
4777                      /* Do not allow the FT-over-DS exception to be used more than
4778                       * once per authentication exchange to guarantee a new TK is
4779                       * used here */
4780                     sta->ft_over_ds = 0;
4781           }
4782 
4783           if (sta->flags & WLAN_STA_HT)
4784                     hostapd_get_ht_capab(hapd, sta->ht_capabilities, &ht_cap);
4785 #ifdef CONFIG_IEEE80211AC
4786           if (sta->flags & WLAN_STA_VHT)
4787                     hostapd_get_vht_capab(hapd, sta->vht_capabilities, &vht_cap);
4788 #endif /* CONFIG_IEEE80211AC */
4789 #ifdef CONFIG_IEEE80211AX
4790           if (sta->flags & WLAN_STA_HE) {
4791                     hostapd_get_he_capab(hapd, sta->he_capab, &he_cap,
4792                                              sta->he_capab_len);
4793           }
4794 #endif /* CONFIG_IEEE80211AX */
4795 #ifdef CONFIG_IEEE80211BE
4796           if (sta->flags & WLAN_STA_EHT)
4797                     hostapd_get_eht_capab(hapd, sta->eht_capab, &eht_cap,
4798                                               sta->eht_capab_len);
4799 #endif /* CONFIG_IEEE80211BE */
4800 
4801           /*
4802            * Add the station with forced WLAN_STA_ASSOC flag. The sta->flags
4803            * will be set when the ACK frame for the (Re)Association Response frame
4804            * is processed (TX status driver event).
4805            */
4806           if (hostapd_sta_add(hapd, sta->addr, sta->aid, sta->capability,
4807                                   sta->supported_rates, sta->supported_rates_len,
4808                                   sta->listen_interval,
4809                                   sta->flags & WLAN_STA_HT ? &ht_cap : NULL,
4810                                   sta->flags & WLAN_STA_VHT ? &vht_cap : NULL,
4811                                   sta->flags & WLAN_STA_HE ? &he_cap : NULL,
4812                                   sta->flags & WLAN_STA_HE ? sta->he_capab_len : 0,
4813                                   sta->flags & WLAN_STA_EHT ? &eht_cap : NULL,
4814                                   sta->flags & WLAN_STA_EHT ? sta->eht_capab_len : 0,
4815                                   sta->he_6ghz_capab,
4816                                   sta->flags | WLAN_STA_ASSOC, sta->qosinfo,
4817                                   sta->vht_opmode, sta->p2p_ie ? 1 : 0,
4818                                   set, mld_link_addr, mld_link_sta)) {
4819                     hostapd_logger(hapd, sta->addr,
4820                                      HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_NOTICE,
4821                                      "Could not %s STA to kernel driver",
4822                                      set ? "set" : "add");
4823 
4824                     if (sta->added_unassoc) {
4825                               hostapd_drv_sta_remove(hapd, sta->addr);
4826                               sta->added_unassoc = 0;
4827                     }
4828 
4829                     return -1;
4830           }
4831 
4832           sta->added_unassoc = 0;
4833 
4834           return 0;
4835 }
4836 
4837 
send_assoc_resp(struct hostapd_data * hapd,struct sta_info * sta,const u8 * addr,u16 status_code,int reassoc,const u8 * ies,size_t ies_len,int rssi,int omit_rsnxe,bool allow_mld_addr_trans)4838 static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
4839                                  const u8 *addr, u16 status_code, int reassoc,
4840                                  const u8 *ies, size_t ies_len, int rssi,
4841                                  int omit_rsnxe, bool allow_mld_addr_trans)
4842 {
4843           int send_len;
4844           u8 *buf;
4845           size_t buflen;
4846           struct ieee80211_mgmt *reply;
4847           u8 *p;
4848           u16 res = WLAN_STATUS_SUCCESS;
4849 
4850           buflen = sizeof(struct ieee80211_mgmt) + 1024;
4851 #ifdef CONFIG_FILS
4852           if (sta && sta->fils_hlp_resp)
4853                     buflen += wpabuf_len(sta->fils_hlp_resp);
4854           if (sta)
4855                     buflen += 150;
4856 #endif /* CONFIG_FILS */
4857 #ifdef CONFIG_OWE
4858           if (sta && (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE))
4859                     buflen += 150;
4860 #endif /* CONFIG_OWE */
4861 #ifdef CONFIG_DPP2
4862           if (sta && sta->dpp_pfs)
4863                     buflen += 5 + sta->dpp_pfs->curve->prime_len;
4864 #endif /* CONFIG_DPP2 */
4865 #ifdef CONFIG_IEEE80211BE
4866           if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
4867                     buflen += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP);
4868                     buflen += 3 + sizeof(struct ieee80211_eht_operation);
4869                     if (hapd->iconf->punct_bitmap)
4870                               buflen += EHT_OPER_DISABLED_SUBCHAN_BITMAP_SIZE;
4871           }
4872 #endif /* CONFIG_IEEE80211BE */
4873 
4874           buf = os_zalloc(buflen);
4875           if (!buf) {
4876                     res = WLAN_STATUS_UNSPECIFIED_FAILURE;
4877                     goto done;
4878           }
4879           reply = (struct ieee80211_mgmt *) buf;
4880           reply->frame_control =
4881                     IEEE80211_FC(WLAN_FC_TYPE_MGMT,
4882                                    (reassoc ? WLAN_FC_STYPE_REASSOC_RESP :
4883                                     WLAN_FC_STYPE_ASSOC_RESP));
4884 
4885           os_memcpy(reply->da, addr, ETH_ALEN);
4886           os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
4887           os_memcpy(reply->bssid, hapd->own_addr, ETH_ALEN);
4888 
4889           send_len = IEEE80211_HDRLEN;
4890           send_len += sizeof(reply->u.assoc_resp);
4891           reply->u.assoc_resp.capab_info =
4892                     host_to_le16(hostapd_own_capab_info(hapd));
4893           reply->u.assoc_resp.status_code = host_to_le16(status_code);
4894 
4895           reply->u.assoc_resp.aid = host_to_le16((sta ? sta->aid : 0) |
4896                                                          BIT(14) | BIT(15));
4897           /* Supported rates */
4898           p = hostapd_eid_supp_rates(hapd, reply->u.assoc_resp.variable);
4899           /* Extended supported rates */
4900           p = hostapd_eid_ext_supp_rates(hapd, p);
4901 
4902           /* Radio measurement capabilities */
4903           p = hostapd_eid_rm_enabled_capab(hapd, p, buf + buflen - p);
4904 
4905 #ifdef CONFIG_MBO
4906           if (status_code == WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS &&
4907               rssi != 0) {
4908                     int delta = hapd->iconf->rssi_reject_assoc_rssi - rssi;
4909 
4910                     p = hostapd_eid_mbo_rssi_assoc_rej(hapd, p, buf + buflen - p,
4911                                                                delta);
4912           }
4913 #endif /* CONFIG_MBO */
4914 
4915 #ifdef CONFIG_IEEE80211R_AP
4916           if (sta && status_code == WLAN_STATUS_SUCCESS) {
4917                     /* IEEE 802.11r: Mobility Domain Information, Fast BSS
4918                      * Transition Information, RSN, [RIC Response] */
4919                     p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, p,
4920                                                             buf + buflen - p,
4921                                                             sta->auth_alg, ies, ies_len,
4922                                                             omit_rsnxe);
4923                     if (!p) {
4924                               wpa_printf(MSG_DEBUG,
4925                                            "FT: Failed to write AssocResp IEs");
4926                               res = WLAN_STATUS_UNSPECIFIED_FAILURE;
4927                               goto done;
4928                     }
4929           }
4930 #endif /* CONFIG_IEEE80211R_AP */
4931 #ifdef CONFIG_FILS
4932           if (sta && status_code == WLAN_STATUS_SUCCESS &&
4933               (sta->auth_alg == WLAN_AUTH_FILS_SK ||
4934                sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
4935                sta->auth_alg == WLAN_AUTH_FILS_PK))
4936                     p = wpa_auth_write_assoc_resp_fils(sta->wpa_sm, p,
4937                                                                buf + buflen - p,
4938                                                                ies, ies_len);
4939 #endif /* CONFIG_FILS */
4940 
4941 #ifdef CONFIG_OWE
4942           if (sta && status_code == WLAN_STATUS_SUCCESS &&
4943               (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE))
4944                     p = wpa_auth_write_assoc_resp_owe(sta->wpa_sm, p,
4945                                                               buf + buflen - p,
4946                                                               ies, ies_len);
4947 #endif /* CONFIG_OWE */
4948 
4949           if (sta && status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY)
4950                     p = hostapd_eid_assoc_comeback_time(hapd, sta, p);
4951 
4952           p = hostapd_eid_ht_capabilities(hapd, p);
4953           p = hostapd_eid_ht_operation(hapd, p);
4954 
4955 #ifdef CONFIG_IEEE80211AC
4956           if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac &&
4957               !is_6ghz_op_class(hapd->iconf->op_class)) {
4958                     u32 nsts = 0, sta_nsts;
4959 
4960                     if (sta && hapd->conf->use_sta_nsts && sta->vht_capabilities) {
4961                               struct ieee80211_vht_capabilities *capa;
4962 
4963                               nsts = (hapd->iface->conf->vht_capab >>
4964                                         VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
4965                               capa = sta->vht_capabilities;
4966                               sta_nsts = (le_to_host32(capa->vht_capabilities_info) >>
4967                                             VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
4968 
4969                               if (nsts < sta_nsts)
4970                                         nsts = 0;
4971                               else
4972                                         nsts = sta_nsts;
4973                     }
4974                     p = hostapd_eid_vht_capabilities(hapd, p, nsts);
4975                     p = hostapd_eid_vht_operation(hapd, p);
4976           }
4977 #endif /* CONFIG_IEEE80211AC */
4978 
4979 #ifdef CONFIG_IEEE80211AX
4980           if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
4981                     p = hostapd_eid_he_capab(hapd, p, IEEE80211_MODE_AP);
4982                     p = hostapd_eid_he_operation(hapd, p);
4983                     p = hostapd_eid_cca(hapd, p);
4984                     p = hostapd_eid_spatial_reuse(hapd, p);
4985                     p = hostapd_eid_he_mu_edca_parameter_set(hapd, p);
4986                     p = hostapd_eid_he_6ghz_band_cap(hapd, p);
4987           }
4988 #endif /* CONFIG_IEEE80211AX */
4989 
4990           p = hostapd_eid_ext_capab(hapd, p, false);
4991           p = hostapd_eid_bss_max_idle_period(hapd, p, sta->max_idle_period);
4992           if (sta && sta->qos_map_enabled)
4993                     p = hostapd_eid_qos_map_set(hapd, p);
4994 
4995 #ifdef CONFIG_FST
4996           if (hapd->iface->fst_ies) {
4997                     os_memcpy(p, wpabuf_head(hapd->iface->fst_ies),
4998                                 wpabuf_len(hapd->iface->fst_ies));
4999                     p += wpabuf_len(hapd->iface->fst_ies);
5000           }
5001 #endif /* CONFIG_FST */
5002 
5003 #ifdef CONFIG_TESTING_OPTIONS
5004           if (hapd->conf->rsnxe_override_ft &&
5005               buf + buflen - p >=
5006               (long int) wpabuf_len(hapd->conf->rsnxe_override_ft) &&
5007               sta && sta->auth_alg == WLAN_AUTH_FT) {
5008                     wpa_printf(MSG_DEBUG, "TESTING: RSNXE FT override");
5009                     os_memcpy(p, wpabuf_head(hapd->conf->rsnxe_override_ft),
5010                                 wpabuf_len(hapd->conf->rsnxe_override_ft));
5011                     p += wpabuf_len(hapd->conf->rsnxe_override_ft);
5012                     goto rsnxe_done;
5013           }
5014 #endif /* CONFIG_TESTING_OPTIONS */
5015           if (!omit_rsnxe)
5016                     p = hostapd_eid_rsnxe(hapd, p, buf + buflen - p);
5017 #ifdef CONFIG_TESTING_OPTIONS
5018 rsnxe_done:
5019 #endif /* CONFIG_TESTING_OPTIONS */
5020 
5021 #ifdef CONFIG_IEEE80211BE
5022           if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
5023                     if (hapd->conf->mld_ap)
5024                               p = hostapd_eid_eht_ml_assoc(hapd, sta, p);
5025                     p = hostapd_eid_eht_capab(hapd, p, IEEE80211_MODE_AP);
5026                     p = hostapd_eid_eht_operation(hapd, p);
5027           }
5028 #endif /* CONFIG_IEEE80211BE */
5029 
5030 #ifdef CONFIG_OWE
5031           if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
5032               sta && sta->owe_ecdh && status_code == WLAN_STATUS_SUCCESS &&
5033               wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_OWE &&
5034               !wpa_auth_sta_get_pmksa(sta->wpa_sm)) {
5035                     struct wpabuf *pub;
5036 
5037                     pub = crypto_ecdh_get_pubkey(sta->owe_ecdh, 0);
5038                     if (!pub) {
5039                               res = WLAN_STATUS_UNSPECIFIED_FAILURE;
5040                               goto done;
5041                     }
5042                     /* OWE Diffie-Hellman Parameter element */
5043                     *p++ = WLAN_EID_EXTENSION; /* Element ID */
5044                     *p++ = 1 + 2 + wpabuf_len(pub); /* Length */
5045                     *p++ = WLAN_EID_EXT_OWE_DH_PARAM; /* Element ID Extension */
5046                     WPA_PUT_LE16(p, sta->owe_group);
5047                     p += 2;
5048                     os_memcpy(p, wpabuf_head(pub), wpabuf_len(pub));
5049                     p += wpabuf_len(pub);
5050                     wpabuf_free(pub);
5051           }
5052 #endif /* CONFIG_OWE */
5053 
5054 #ifdef CONFIG_DPP2
5055           if (DPP_VERSION > 1 && (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) &&
5056               sta && sta->dpp_pfs && status_code == WLAN_STATUS_SUCCESS &&
5057               wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_DPP) {
5058                     os_memcpy(p, wpabuf_head(sta->dpp_pfs->ie),
5059                                 wpabuf_len(sta->dpp_pfs->ie));
5060                     p += wpabuf_len(sta->dpp_pfs->ie);
5061           }
5062 #endif /* CONFIG_DPP2 */
5063 
5064 #ifdef CONFIG_IEEE80211AC
5065           if (sta && hapd->conf->vendor_vht && (sta->flags & WLAN_STA_VENDOR_VHT))
5066                     p = hostapd_eid_vendor_vht(hapd, p);
5067 #endif /* CONFIG_IEEE80211AC */
5068 
5069           if (sta && (sta->flags & WLAN_STA_WMM))
5070                     p = hostapd_eid_wmm(hapd, p);
5071 
5072 #ifdef CONFIG_WPS
5073           if (sta &&
5074               ((sta->flags & WLAN_STA_WPS) ||
5075                ((sta->flags & WLAN_STA_MAYBE_WPS) && hapd->conf->wpa))) {
5076                     struct wpabuf *wps = wps_build_assoc_resp_ie();
5077                     if (wps) {
5078                               os_memcpy(p, wpabuf_head(wps), wpabuf_len(wps));
5079                               p += wpabuf_len(wps);
5080                               wpabuf_free(wps);
5081                     }
5082           }
5083 #endif /* CONFIG_WPS */
5084 
5085           if (sta && (sta->flags & WLAN_STA_MULTI_AP))
5086                     p = hostapd_eid_multi_ap(hapd, p, buf + buflen - p);
5087 
5088 #ifdef CONFIG_P2P
5089           if (sta && sta->p2p_ie && hapd->p2p_group) {
5090                     struct wpabuf *p2p_resp_ie;
5091                     enum p2p_status_code status;
5092                     switch (status_code) {
5093                     case WLAN_STATUS_SUCCESS:
5094                               status = P2P_SC_SUCCESS;
5095                               break;
5096                     case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA:
5097                               status = P2P_SC_FAIL_LIMIT_REACHED;
5098                               break;
5099                     default:
5100                               status = P2P_SC_FAIL_INVALID_PARAMS;
5101                               break;
5102                     }
5103                     p2p_resp_ie = p2p_group_assoc_resp_ie(hapd->p2p_group, status);
5104                     if (p2p_resp_ie) {
5105                               os_memcpy(p, wpabuf_head(p2p_resp_ie),
5106                                           wpabuf_len(p2p_resp_ie));
5107                               p += wpabuf_len(p2p_resp_ie);
5108                               wpabuf_free(p2p_resp_ie);
5109                     }
5110           }
5111 #endif /* CONFIG_P2P */
5112 
5113 #ifdef CONFIG_P2P_MANAGER
5114           if (hapd->conf->p2p & P2P_MANAGE)
5115                     p = hostapd_eid_p2p_manage(hapd, p);
5116 #endif /* CONFIG_P2P_MANAGER */
5117 
5118           p = hostapd_eid_mbo(hapd, p, buf + buflen - p);
5119 
5120           if (hapd->conf->assocresp_elements &&
5121               (size_t) (buf + buflen - p) >=
5122               wpabuf_len(hapd->conf->assocresp_elements)) {
5123                     os_memcpy(p, wpabuf_head(hapd->conf->assocresp_elements),
5124                                 wpabuf_len(hapd->conf->assocresp_elements));
5125                     p += wpabuf_len(hapd->conf->assocresp_elements);
5126           }
5127 
5128           send_len += p - reply->u.assoc_resp.variable;
5129 
5130 #ifdef CONFIG_FILS
5131           if (sta &&
5132               (sta->auth_alg == WLAN_AUTH_FILS_SK ||
5133                sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
5134                sta->auth_alg == WLAN_AUTH_FILS_PK) &&
5135               status_code == WLAN_STATUS_SUCCESS) {
5136                     struct ieee802_11_elems elems;
5137 
5138                     if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) ==
5139                         ParseFailed || !elems.fils_session) {
5140                               res = WLAN_STATUS_UNSPECIFIED_FAILURE;
5141                               goto done;
5142                     }
5143 
5144                     /* FILS Session */
5145                     *p++ = WLAN_EID_EXTENSION; /* Element ID */
5146                     *p++ = 1 + FILS_SESSION_LEN; /* Length */
5147                     *p++ = WLAN_EID_EXT_FILS_SESSION; /* Element ID Extension */
5148                     os_memcpy(p, elems.fils_session, FILS_SESSION_LEN);
5149                     send_len += 2 + 1 + FILS_SESSION_LEN;
5150 
5151                     send_len = fils_encrypt_assoc(sta->wpa_sm, buf, send_len,
5152                                                         buflen, sta->fils_hlp_resp);
5153                     if (send_len < 0) {
5154                               res = WLAN_STATUS_UNSPECIFIED_FAILURE;
5155                               goto done;
5156                     }
5157           }
5158 #endif /* CONFIG_FILS */
5159 
5160           if (hostapd_drv_send_mlme(hapd, reply, send_len, 0, NULL, 0, 0) < 0) {
5161                     wpa_printf(MSG_INFO, "Failed to send assoc resp: %s",
5162                                  strerror(errno));
5163                     res = WLAN_STATUS_UNSPECIFIED_FAILURE;
5164           }
5165 
5166 done:
5167           os_free(buf);
5168           return res;
5169 }
5170 
5171 
5172 #ifdef CONFIG_OWE
owe_assoc_req_process(struct hostapd_data * hapd,struct sta_info * sta,const u8 * owe_dh,u8 owe_dh_len,u8 * owe_buf,size_t owe_buf_len,u16 * status)5173 u8 * owe_assoc_req_process(struct hostapd_data *hapd, struct sta_info *sta,
5174                                  const u8 *owe_dh, u8 owe_dh_len,
5175                                  u8 *owe_buf, size_t owe_buf_len, u16 *status)
5176 {
5177 #ifdef CONFIG_TESTING_OPTIONS
5178           if (hapd->conf->own_ie_override) {
5179                     wpa_printf(MSG_DEBUG, "OWE: Using IE override");
5180                     *status = WLAN_STATUS_SUCCESS;
5181                     return wpa_auth_write_assoc_resp_owe(sta->wpa_sm, owe_buf,
5182                                                                  owe_buf_len, NULL, 0);
5183           }
5184 #endif /* CONFIG_TESTING_OPTIONS */
5185 
5186           if (wpa_auth_sta_get_pmksa(sta->wpa_sm)) {
5187                     wpa_printf(MSG_DEBUG, "OWE: Using PMKSA caching");
5188                     owe_buf = wpa_auth_write_assoc_resp_owe(sta->wpa_sm, owe_buf,
5189                                                                       owe_buf_len, NULL, 0);
5190                     *status = WLAN_STATUS_SUCCESS;
5191                     return owe_buf;
5192           }
5193 
5194           if (sta->owe_pmk && sta->external_dh_updated) {
5195                     wpa_printf(MSG_DEBUG, "OWE: Using previously derived PMK");
5196                     *status = WLAN_STATUS_SUCCESS;
5197                     return owe_buf;
5198           }
5199 
5200           *status = owe_process_assoc_req(hapd, sta, owe_dh, owe_dh_len);
5201           if (*status != WLAN_STATUS_SUCCESS)
5202                     return NULL;
5203 
5204           owe_buf = wpa_auth_write_assoc_resp_owe(sta->wpa_sm, owe_buf,
5205                                                             owe_buf_len, NULL, 0);
5206 
5207           if (sta->owe_ecdh && owe_buf) {
5208                     struct wpabuf *pub;
5209 
5210                     pub = crypto_ecdh_get_pubkey(sta->owe_ecdh, 0);
5211                     if (!pub) {
5212                               *status = WLAN_STATUS_UNSPECIFIED_FAILURE;
5213                               return owe_buf;
5214                     }
5215 
5216                     /* OWE Diffie-Hellman Parameter element */
5217                     *owe_buf++ = WLAN_EID_EXTENSION; /* Element ID */
5218                     *owe_buf++ = 1 + 2 + wpabuf_len(pub); /* Length */
5219                     *owe_buf++ = WLAN_EID_EXT_OWE_DH_PARAM; /* Element ID Extension
5220                                                                        */
5221                     WPA_PUT_LE16(owe_buf, sta->owe_group);
5222                     owe_buf += 2;
5223                     os_memcpy(owe_buf, wpabuf_head(pub), wpabuf_len(pub));
5224                     owe_buf += wpabuf_len(pub);
5225                     wpabuf_free(pub);
5226           }
5227 
5228           return owe_buf;
5229 }
5230 #endif /* CONFIG_OWE */
5231 
5232 
5233 #ifdef CONFIG_FILS
5234 
fils_hlp_finish_assoc(struct hostapd_data * hapd,struct sta_info * sta)5235 void fils_hlp_finish_assoc(struct hostapd_data *hapd, struct sta_info *sta)
5236 {
5237           u16 reply_res;
5238 
5239           wpa_printf(MSG_DEBUG, "FILS: Finish association with " MACSTR,
5240                        MAC2STR(sta->addr));
5241           eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
5242           if (!sta->fils_pending_assoc_req)
5243                     return;
5244           reply_res = send_assoc_resp(hapd, sta, sta->addr, WLAN_STATUS_SUCCESS,
5245                                             sta->fils_pending_assoc_is_reassoc,
5246                                             sta->fils_pending_assoc_req,
5247                                             sta->fils_pending_assoc_req_len, 0, 0,
5248                                             true);
5249           os_free(sta->fils_pending_assoc_req);
5250           sta->fils_pending_assoc_req = NULL;
5251           sta->fils_pending_assoc_req_len = 0;
5252           wpabuf_free(sta->fils_hlp_resp);
5253           sta->fils_hlp_resp = NULL;
5254           wpabuf_free(sta->hlp_dhcp_discover);
5255           sta->hlp_dhcp_discover = NULL;
5256 
5257           /*
5258            * Remove the station in case transmission of a success response fails.
5259            * At this point the station was already added associated to the driver.
5260            */
5261           if (reply_res != WLAN_STATUS_SUCCESS)
5262                     hostapd_drv_sta_remove(hapd, sta->addr);
5263 }
5264 
5265 
fils_hlp_timeout(void * eloop_ctx,void * eloop_data)5266 void fils_hlp_timeout(void *eloop_ctx, void *eloop_data)
5267 {
5268           struct hostapd_data *hapd = eloop_ctx;
5269           struct sta_info *sta = eloop_data;
5270 
5271           wpa_printf(MSG_DEBUG,
5272                        "FILS: HLP response timeout - continue with association response for "
5273                        MACSTR, MAC2STR(sta->addr));
5274           if (sta->fils_drv_assoc_finish)
5275                     hostapd_notify_assoc_fils_finish(hapd, sta);
5276           else
5277                     fils_hlp_finish_assoc(hapd, sta);
5278 }
5279 
5280 #endif /* CONFIG_FILS */
5281 
5282 
5283 #ifdef CONFIG_IEEE80211BE
handle_mlo_translate(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len,bool reassoc,struct hostapd_data ** assoc_hapd)5284 static struct sta_info * handle_mlo_translate(struct hostapd_data *hapd,
5285                                                         const struct ieee80211_mgmt *mgmt,
5286                                                         size_t len, bool reassoc,
5287                                                         struct hostapd_data **assoc_hapd)
5288 {
5289           struct sta_info *sta;
5290           struct ieee802_11_elems elems;
5291           u8 mld_addr[ETH_ALEN];
5292           const u8 *pos;
5293 
5294           if (!hapd->iconf->ieee80211be || hapd->conf->disable_11be)
5295                     return NULL;
5296 
5297           if (reassoc) {
5298                     len -= IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req);
5299                     pos = mgmt->u.reassoc_req.variable;
5300           } else {
5301                     len -= IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req);
5302                     pos = mgmt->u.assoc_req.variable;
5303           }
5304 
5305           if (ieee802_11_parse_elems(pos, len, &elems, 1) == ParseFailed)
5306                     return NULL;
5307 
5308           if (hostapd_process_ml_assoc_req_addr(hapd, elems.basic_mle,
5309                                                         elems.basic_mle_len,
5310                                                         mld_addr))
5311                     return NULL;
5312 
5313           sta = ap_get_sta(hapd, mld_addr);
5314           if (!sta)
5315                     return NULL;
5316 
5317           wpa_printf(MSG_DEBUG, "MLD: assoc: mld=" MACSTR ", link=" MACSTR,
5318                        MAC2STR(mld_addr), MAC2STR(mgmt->sa));
5319 
5320           return hostapd_ml_get_assoc_sta(hapd, sta, assoc_hapd);
5321 }
5322 #endif /* CONFIG_IEEE80211BE */
5323 
5324 
handle_assoc(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len,int reassoc,int rssi)5325 static void handle_assoc(struct hostapd_data *hapd,
5326                                const struct ieee80211_mgmt *mgmt, size_t len,
5327                                int reassoc, int rssi)
5328 {
5329           u16 capab_info, listen_interval, seq_ctrl, fc;
5330           int resp = WLAN_STATUS_SUCCESS;
5331           u16 reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE;
5332           const u8 *pos;
5333           int left, i;
5334           struct sta_info *sta;
5335           u8 *tmp = NULL;
5336 #ifdef CONFIG_FILS
5337           int delay_assoc = 0;
5338 #endif /* CONFIG_FILS */
5339           int omit_rsnxe = 0;
5340           bool set_beacon = false;
5341           bool mld_addrs_not_translated = false;
5342 
5343           if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
5344                                               sizeof(mgmt->u.assoc_req))) {
5345                     wpa_printf(MSG_INFO, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
5346                                  reassoc, (unsigned long) len);
5347                     return;
5348           }
5349 
5350 #ifdef CONFIG_TESTING_OPTIONS
5351           if (reassoc) {
5352                     if (hapd->iconf->ignore_reassoc_probability > 0.0 &&
5353                         drand48() < hapd->iconf->ignore_reassoc_probability) {
5354                               wpa_printf(MSG_INFO,
5355                                            "TESTING: ignoring reassoc request from "
5356                                            MACSTR, MAC2STR(mgmt->sa));
5357                               return;
5358                     }
5359           } else {
5360                     if (hapd->iconf->ignore_assoc_probability > 0.0 &&
5361                         drand48() < hapd->iconf->ignore_assoc_probability) {
5362                               wpa_printf(MSG_INFO,
5363                                            "TESTING: ignoring assoc request from "
5364                                            MACSTR, MAC2STR(mgmt->sa));
5365                               return;
5366                     }
5367           }
5368 #endif /* CONFIG_TESTING_OPTIONS */
5369 
5370           fc = le_to_host16(mgmt->frame_control);
5371           seq_ctrl = le_to_host16(mgmt->seq_ctrl);
5372 
5373           if (reassoc) {
5374                     capab_info = le_to_host16(mgmt->u.reassoc_req.capab_info);
5375                     listen_interval = le_to_host16(
5376                               mgmt->u.reassoc_req.listen_interval);
5377                     wpa_printf(MSG_DEBUG, "reassociation request: STA=" MACSTR
5378                                  " capab_info=0x%02x listen_interval=%d current_ap="
5379                                  MACSTR " seq_ctrl=0x%x%s",
5380                                  MAC2STR(mgmt->sa), capab_info, listen_interval,
5381                                  MAC2STR(mgmt->u.reassoc_req.current_ap),
5382                                  seq_ctrl, (fc & WLAN_FC_RETRY) ? " retry" : "");
5383                     left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req));
5384                     pos = mgmt->u.reassoc_req.variable;
5385           } else {
5386                     capab_info = le_to_host16(mgmt->u.assoc_req.capab_info);
5387                     listen_interval = le_to_host16(
5388                               mgmt->u.assoc_req.listen_interval);
5389                     wpa_printf(MSG_DEBUG, "association request: STA=" MACSTR
5390                                  " capab_info=0x%02x listen_interval=%d "
5391                                  "seq_ctrl=0x%x%s",
5392                                  MAC2STR(mgmt->sa), capab_info, listen_interval,
5393                                  seq_ctrl, (fc & WLAN_FC_RETRY) ? " retry" : "");
5394                     left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req));
5395                     pos = mgmt->u.assoc_req.variable;
5396           }
5397 
5398           sta = ap_get_sta(hapd, mgmt->sa);
5399 
5400 #ifdef CONFIG_IEEE80211BE
5401           /*
5402            * It is possible that the association frame is from an associated
5403            * non-AP MLD station, that tries to re-associate using different link
5404            * addresses. In such a case, try to find the station based on the AP
5405            * MLD MAC address.
5406            */
5407           if (!sta) {
5408                     struct hostapd_data *assoc_hapd;
5409 
5410                     sta = handle_mlo_translate(hapd, mgmt, len, reassoc,
5411                                                      &assoc_hapd);
5412                     if (sta) {
5413                               wpa_printf(MSG_DEBUG,
5414                                            "MLD: Switching to assoc hapd/station");
5415                               hapd = assoc_hapd;
5416                               mld_addrs_not_translated = true;
5417                     }
5418           }
5419 #endif /* CONFIG_IEEE80211BE */
5420 
5421 #ifdef CONFIG_IEEE80211R_AP
5422           if (sta && sta->auth_alg == WLAN_AUTH_FT &&
5423               (sta->flags & WLAN_STA_AUTH) == 0) {
5424                     wpa_printf(MSG_DEBUG, "FT: Allow STA " MACSTR " to associate "
5425                                  "prior to authentication since it is using "
5426                                  "over-the-DS FT", MAC2STR(mgmt->sa));
5427 
5428                     /*
5429                      * Mark station as authenticated, to avoid adding station
5430                      * entry in the driver as associated and not authenticated
5431                      */
5432                     sta->flags |= WLAN_STA_AUTH;
5433           } else
5434 #endif /* CONFIG_IEEE80211R_AP */
5435           if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) {
5436                     if (hapd->iface->current_mode &&
5437                         hapd->iface->current_mode->mode ==
5438                               HOSTAPD_MODE_IEEE80211AD) {
5439                               int acl_res;
5440                               struct radius_sta info;
5441 
5442                               acl_res = ieee802_11_allowed_address(hapd, mgmt->sa,
5443                                                                            (const u8 *) mgmt,
5444                                                                            len, &info);
5445                               if (acl_res == HOSTAPD_ACL_REJECT) {
5446                                         wpa_msg(hapd->msg_ctx, MSG_DEBUG,
5447                                                   "Ignore Association Request frame from "
5448                                                   MACSTR " due to ACL reject",
5449                                                   MAC2STR(mgmt->sa));
5450                                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
5451                                         goto fail;
5452                               }
5453                               if (acl_res == HOSTAPD_ACL_PENDING)
5454                                         return;
5455 
5456                               /* DMG/IEEE 802.11ad does not use authentication.
5457                                * Allocate sta entry upon association. */
5458                               sta = ap_sta_add(hapd, mgmt->sa);
5459                               if (!sta) {
5460                                         hostapd_logger(hapd, mgmt->sa,
5461                                                          HOSTAPD_MODULE_IEEE80211,
5462                                                          HOSTAPD_LEVEL_INFO,
5463                                                          "Failed to add STA");
5464                                         resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
5465                                         goto fail;
5466                               }
5467 
5468                               acl_res = ieee802_11_set_radius_info(
5469                                         hapd, sta, acl_res, &info);
5470                               if (acl_res) {
5471                                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
5472                                         goto fail;
5473                               }
5474 
5475                               hostapd_logger(hapd, sta->addr,
5476                                                HOSTAPD_MODULE_IEEE80211,
5477                                                HOSTAPD_LEVEL_DEBUG,
5478                                                "Skip authentication for DMG/IEEE 802.11ad");
5479                               sta->flags |= WLAN_STA_AUTH;
5480                               wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
5481                               sta->auth_alg = WLAN_AUTH_OPEN;
5482                     } else {
5483                               hostapd_logger(hapd, mgmt->sa,
5484                                                HOSTAPD_MODULE_IEEE80211,
5485                                                HOSTAPD_LEVEL_INFO,
5486                                                "Station tried to associate before authentication (aid=%d flags=0x%x)",
5487                                                sta ? sta->aid : -1,
5488                                                sta ? sta->flags : 0);
5489                               send_deauth(hapd, mgmt->sa,
5490                                             WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA);
5491                               return;
5492                     }
5493           }
5494 
5495           if ((fc & WLAN_FC_RETRY) &&
5496               sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
5497               sta->last_seq_ctrl == seq_ctrl &&
5498               sta->last_subtype == (reassoc ? WLAN_FC_STYPE_REASSOC_REQ :
5499                                           WLAN_FC_STYPE_ASSOC_REQ)) {
5500                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
5501                                      HOSTAPD_LEVEL_DEBUG,
5502                                      "Drop repeated association frame seq_ctrl=0x%x",
5503                                      seq_ctrl);
5504                     return;
5505           }
5506           sta->last_seq_ctrl = seq_ctrl;
5507           sta->last_subtype = reassoc ? WLAN_FC_STYPE_REASSOC_REQ :
5508                     WLAN_FC_STYPE_ASSOC_REQ;
5509 
5510           if (hapd->tkip_countermeasures) {
5511                     resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
5512                     goto fail;
5513           }
5514 
5515           if (listen_interval > hapd->conf->max_listen_interval) {
5516                     hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
5517                                      HOSTAPD_LEVEL_DEBUG,
5518                                      "Too large Listen Interval (%d)",
5519                                      listen_interval);
5520                     resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
5521                     goto fail;
5522           }
5523 
5524 #ifdef CONFIG_MBO
5525           if (hapd->conf->mbo_enabled && hapd->mbo_assoc_disallow) {
5526                     resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
5527                     goto fail;
5528           }
5529 
5530           if (hapd->iconf->rssi_reject_assoc_rssi && rssi &&
5531               rssi < hapd->iconf->rssi_reject_assoc_rssi &&
5532               (sta->auth_rssi == 0 ||
5533                sta->auth_rssi < hapd->iconf->rssi_reject_assoc_rssi)) {
5534                     resp = WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS;
5535                     goto fail;
5536           }
5537 #endif /* CONFIG_MBO */
5538 
5539           if (hapd->conf->wpa && check_sa_query(hapd, sta, reassoc)) {
5540                     resp = WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
5541                     goto fail;
5542           }
5543 
5544           /*
5545            * sta->capability is used in check_assoc_ies() for RRM enabled
5546            * capability element.
5547            */
5548           sta->capability = capab_info;
5549 
5550 #ifdef CONFIG_FILS
5551           if (sta->auth_alg == WLAN_AUTH_FILS_SK ||
5552               sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
5553               sta->auth_alg == WLAN_AUTH_FILS_PK) {
5554                     int res;
5555 
5556                     /* The end of the payload is encrypted. Need to decrypt it
5557                      * before parsing. */
5558 
5559                     tmp = os_memdup(pos, left);
5560                     if (!tmp) {
5561                               resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
5562                               goto fail;
5563                     }
5564 
5565                     res = fils_decrypt_assoc(sta->wpa_sm, sta->fils_session, mgmt,
5566                                                    len, tmp, left);
5567                     if (res < 0) {
5568                               resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
5569                               goto fail;
5570                     }
5571                     pos = tmp;
5572                     left = res;
5573           }
5574 #endif /* CONFIG_FILS */
5575 
5576           /* followed by SSID and Supported rates; and HT capabilities if 802.11n
5577            * is used */
5578           resp = check_assoc_ies(hapd, sta, pos, left, reassoc);
5579           if (resp != WLAN_STATUS_SUCCESS)
5580                     goto fail;
5581           omit_rsnxe = !get_ie(pos, left, WLAN_EID_RSNX);
5582 
5583           if (hostapd_get_aid(hapd, sta) < 0) {
5584                     hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
5585                                      HOSTAPD_LEVEL_INFO, "No room for more AIDs");
5586                     resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
5587                     goto fail;
5588           }
5589 
5590           sta->listen_interval = listen_interval;
5591 
5592           if (hapd->iface->current_mode &&
5593               hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
5594                     sta->flags |= WLAN_STA_NONERP;
5595           for (i = 0; i < sta->supported_rates_len; i++) {
5596                     if ((sta->supported_rates[i] & 0x7f) > 22) {
5597                               sta->flags &= ~WLAN_STA_NONERP;
5598                               break;
5599                     }
5600           }
5601           if (sta->flags & WLAN_STA_NONERP && !sta->nonerp_set) {
5602                     sta->nonerp_set = 1;
5603                     hapd->iface->num_sta_non_erp++;
5604                     if (hapd->iface->num_sta_non_erp == 1)
5605                               set_beacon = true;
5606           }
5607 
5608           if (!(sta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) &&
5609               !sta->no_short_slot_time_set) {
5610                     sta->no_short_slot_time_set = 1;
5611                     hapd->iface->num_sta_no_short_slot_time++;
5612                     if (hapd->iface->current_mode &&
5613                         hapd->iface->current_mode->mode ==
5614                         HOSTAPD_MODE_IEEE80211G &&
5615                         hapd->iface->num_sta_no_short_slot_time == 1)
5616                               set_beacon = true;
5617           }
5618 
5619           if (sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
5620                     sta->flags |= WLAN_STA_SHORT_PREAMBLE;
5621           else
5622                     sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
5623 
5624           if (!(sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
5625               !sta->no_short_preamble_set) {
5626                     sta->no_short_preamble_set = 1;
5627                     hapd->iface->num_sta_no_short_preamble++;
5628                     if (hapd->iface->current_mode &&
5629                         hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
5630                         && hapd->iface->num_sta_no_short_preamble == 1)
5631                               set_beacon = true;
5632           }
5633 
5634           if (update_ht_state(hapd, sta) > 0)
5635                     set_beacon = true;
5636 
5637           hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
5638                            HOSTAPD_LEVEL_DEBUG,
5639                            "association OK (aid %d)", sta->aid);
5640           /* Station will be marked associated, after it acknowledges AssocResp
5641            */
5642           sta->flags |= WLAN_STA_ASSOC_REQ_OK;
5643 
5644           if ((sta->flags & WLAN_STA_MFP) && sta->sa_query_timed_out) {
5645                     wpa_printf(MSG_DEBUG, "Allowing %sassociation after timed out "
5646                                  "SA Query procedure", reassoc ? "re" : "");
5647                     /* TODO: Send a protected Disassociate frame to the STA using
5648                      * the old key and Reason Code "Previous Authentication no
5649                      * longer valid". Make sure this is only sent protected since
5650                      * unprotected frame would be received by the STA that is now
5651                      * trying to associate.
5652                      */
5653           }
5654 
5655           /* Make sure that the previously registered inactivity timer will not
5656            * remove the STA immediately. */
5657           sta->timeout_next = STA_NULLFUNC;
5658 
5659 #ifdef CONFIG_TAXONOMY
5660           taxonomy_sta_info_assoc_req(hapd, sta, pos, left);
5661 #endif /* CONFIG_TAXONOMY */
5662 
5663           sta->pending_wds_enable = 0;
5664 
5665 #ifdef CONFIG_FILS
5666           if (sta->auth_alg == WLAN_AUTH_FILS_SK ||
5667               sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
5668               sta->auth_alg == WLAN_AUTH_FILS_PK) {
5669                     if (fils_process_hlp(hapd, sta, pos, left) > 0)
5670                               delay_assoc = 1;
5671           }
5672 #endif /* CONFIG_FILS */
5673 
5674           if (set_beacon)
5675                     ieee802_11_update_beacons(hapd->iface);
5676 
5677  fail:
5678 
5679           /*
5680            * In case of a successful response, add the station to the driver.
5681            * Otherwise, the kernel may ignore Data frames before we process the
5682            * ACK frame (TX status). In case of a failure, this station will be
5683            * removed.
5684            *
5685            * Note that this is not compliant with the IEEE 802.11 standard that
5686            * states that a non-AP station should transition into the
5687            * authenticated/associated state only after the station acknowledges
5688            * the (Re)Association Response frame. However, still do this as:
5689            *
5690            * 1. In case the station does not acknowledge the (Re)Association
5691            *    Response frame, it will be removed.
5692            * 2. Data frames will be dropped in the kernel until the station is
5693            *    set into authorized state, and there are no significant known
5694            *    issues with processing other non-Data Class 3 frames during this
5695            *    window.
5696            */
5697           if (sta)
5698                     hostapd_process_assoc_ml_info(hapd, sta, pos, left, reassoc,
5699                                                         resp, false);
5700 
5701           if (resp == WLAN_STATUS_SUCCESS && sta &&
5702               add_associated_sta(hapd, sta, reassoc))
5703                     resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
5704 
5705 #ifdef CONFIG_FILS
5706           if (sta && delay_assoc && resp == WLAN_STATUS_SUCCESS &&
5707               eloop_is_timeout_registered(fils_hlp_timeout, hapd, sta) &&
5708               sta->fils_pending_assoc_req) {
5709                     /* Do not reschedule fils_hlp_timeout in case the station
5710                      * retransmits (Re)Association Request frame while waiting for
5711                      * the previously started FILS HLP wait, so that the timeout can
5712                      * be determined from the first pending attempt. */
5713                     wpa_printf(MSG_DEBUG,
5714                                  "FILS: Continue waiting for HLP processing before sending (Re)Association Response frame to "
5715                                  MACSTR, MAC2STR(sta->addr));
5716                     os_free(tmp);
5717                     return;
5718           }
5719           if (sta) {
5720                     eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
5721                     os_free(sta->fils_pending_assoc_req);
5722                     sta->fils_pending_assoc_req = NULL;
5723                     sta->fils_pending_assoc_req_len = 0;
5724                     wpabuf_free(sta->fils_hlp_resp);
5725                     sta->fils_hlp_resp = NULL;
5726           }
5727           if (sta && delay_assoc && resp == WLAN_STATUS_SUCCESS) {
5728                     sta->fils_pending_assoc_req = tmp;
5729                     sta->fils_pending_assoc_req_len = left;
5730                     sta->fils_pending_assoc_is_reassoc = reassoc;
5731                     sta->fils_drv_assoc_finish = 0;
5732                     wpa_printf(MSG_DEBUG,
5733                                  "FILS: Waiting for HLP processing before sending (Re)Association Response frame to "
5734                                  MACSTR, MAC2STR(sta->addr));
5735                     eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
5736                     eloop_register_timeout(0, hapd->conf->fils_hlp_wait_time * 1024,
5737                                                fils_hlp_timeout, hapd, sta);
5738                     return;
5739           }
5740 #endif /* CONFIG_FILS */
5741 
5742           if (resp >= 0)
5743                     reply_res = send_assoc_resp(hapd,
5744                                                       mld_addrs_not_translated ?
5745                                                       NULL : sta,
5746                                                       mgmt->sa, resp, reassoc,
5747                                                       pos, left, rssi, omit_rsnxe,
5748                                                       !mld_addrs_not_translated);
5749           os_free(tmp);
5750 
5751           /*
5752            * Remove the station in case transmission of a success response fails
5753            * (the STA was added associated to the driver) or if the station was
5754            * previously added unassociated.
5755            */
5756           if (sta && ((reply_res != WLAN_STATUS_SUCCESS &&
5757                          resp == WLAN_STATUS_SUCCESS) || sta->added_unassoc)) {
5758                     hostapd_drv_sta_remove(hapd, sta->addr);
5759                     sta->added_unassoc = 0;
5760           }
5761 }
5762 
5763 
hostapd_deauth_sta(struct hostapd_data * hapd,struct sta_info * sta,const struct ieee80211_mgmt * mgmt)5764 static void hostapd_deauth_sta(struct hostapd_data *hapd,
5765                                      struct sta_info *sta,
5766                                      const struct ieee80211_mgmt *mgmt)
5767 {
5768           wpa_msg(hapd->msg_ctx, MSG_DEBUG,
5769                     "deauthentication: STA=" MACSTR " reason_code=%d",
5770                     MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code));
5771 
5772           ap_sta_set_authorized(hapd, sta, 0);
5773           sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ;
5774           sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC |
5775                               WLAN_STA_ASSOC_REQ_OK);
5776           hostapd_set_sta_flags(hapd, sta);
5777           wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
5778           hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
5779                            HOSTAPD_LEVEL_DEBUG, "deauthenticated");
5780           mlme_deauthenticate_indication(
5781                     hapd, sta, le_to_host16(mgmt->u.deauth.reason_code));
5782           sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
5783           ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
5784           ap_free_sta(hapd, sta);
5785 }
5786 
5787 
hostapd_disassoc_sta(struct hostapd_data * hapd,struct sta_info * sta,const struct ieee80211_mgmt * mgmt)5788 static void hostapd_disassoc_sta(struct hostapd_data *hapd,
5789                                          struct sta_info *sta,
5790                                          const struct ieee80211_mgmt *mgmt)
5791 {
5792           wpa_msg(hapd->msg_ctx, MSG_DEBUG,
5793                     "disassocation: STA=" MACSTR " reason_code=%d",
5794                     MAC2STR(mgmt->sa), le_to_host16(mgmt->u.disassoc.reason_code));
5795 
5796           ap_sta_set_authorized(hapd, sta, 0);
5797           sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ;
5798           sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK);
5799           hostapd_set_sta_flags(hapd, sta);
5800           wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
5801           hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
5802                            HOSTAPD_LEVEL_INFO, "disassociated");
5803           sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
5804           ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
5805           /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
5806            * authenticated. */
5807           accounting_sta_stop(hapd, sta);
5808           ieee802_1x_free_station(hapd, sta);
5809           if (sta->ipaddr)
5810                     hostapd_drv_br_delete_ip_neigh(hapd, 4, (u8 *) &sta->ipaddr);
5811           ap_sta_ip6addr_del(hapd, sta);
5812           hostapd_drv_sta_remove(hapd, sta->addr);
5813           sta->added_unassoc = 0;
5814 
5815           if (sta->timeout_next == STA_NULLFUNC ||
5816               sta->timeout_next == STA_DISASSOC) {
5817                     sta->timeout_next = STA_DEAUTH;
5818                     eloop_cancel_timeout(ap_handle_timer, hapd, sta);
5819                     eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
5820                                                hapd, sta);
5821           }
5822 
5823           mlme_disassociate_indication(
5824                     hapd, sta, le_to_host16(mgmt->u.disassoc.reason_code));
5825 
5826           /* DMG/IEEE 802.11ad does not use deauthication. Deallocate sta upon
5827            * disassociation. */
5828           if (hapd->iface->current_mode &&
5829               hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211AD) {
5830                     sta->flags &= ~WLAN_STA_AUTH;
5831                     wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
5832                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
5833                                      HOSTAPD_LEVEL_DEBUG, "deauthenticated");
5834                     ap_free_sta(hapd, sta);
5835           }
5836 }
5837 
5838 
hostapd_ml_handle_disconnect(struct hostapd_data * hapd,struct sta_info * sta,const struct ieee80211_mgmt * mgmt,bool disassoc)5839 static bool hostapd_ml_handle_disconnect(struct hostapd_data *hapd,
5840                                                    struct sta_info *sta,
5841                                                    const struct ieee80211_mgmt *mgmt,
5842                                                    bool disassoc)
5843 {
5844 #ifdef CONFIG_IEEE80211BE
5845           struct hostapd_data *assoc_hapd, *tmp_hapd;
5846           struct sta_info *assoc_sta;
5847           struct sta_info *tmp_sta;
5848 
5849           if (!hostapd_is_mld_ap(hapd))
5850                     return false;
5851 
5852           /*
5853            * Get the station on which the association was performed, as it holds
5854            * the information about all the other links.
5855            */
5856           assoc_sta = hostapd_ml_get_assoc_sta(hapd, sta, &assoc_hapd);
5857           if (!assoc_sta)
5858                     return false;
5859 
5860           for_each_mld_link(tmp_hapd, assoc_hapd) {
5861                     if (tmp_hapd == assoc_hapd)
5862                               continue;
5863 
5864                     if (!assoc_sta->mld_info.links[tmp_hapd->mld_link_id].valid)
5865                               continue;
5866 
5867                     for (tmp_sta = tmp_hapd->sta_list; tmp_sta;
5868                          tmp_sta = tmp_sta->next) {
5869                               if (tmp_sta->mld_assoc_link_id !=
5870                                   assoc_sta->mld_assoc_link_id ||
5871                                   tmp_sta->aid != assoc_sta->aid)
5872                                         continue;
5873 
5874                               if (!disassoc)
5875                                         hostapd_deauth_sta(tmp_hapd, tmp_sta, mgmt);
5876                               else
5877                                         hostapd_disassoc_sta(tmp_hapd, tmp_sta, mgmt);
5878                               break;
5879                     }
5880           }
5881 
5882           /* Remove the station on which the association was performed. */
5883           if (!disassoc)
5884                     hostapd_deauth_sta(assoc_hapd, assoc_sta, mgmt);
5885           else
5886                     hostapd_disassoc_sta(assoc_hapd, assoc_sta, mgmt);
5887 
5888           return true;
5889 #else /* CONFIG_IEEE80211BE */
5890           return false;
5891 #endif /* CONFIG_IEEE80211BE */
5892 }
5893 
5894 
handle_disassoc(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len)5895 static void handle_disassoc(struct hostapd_data *hapd,
5896                                   const struct ieee80211_mgmt *mgmt, size_t len)
5897 {
5898           struct sta_info *sta;
5899 
5900           if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.disassoc)) {
5901                     wpa_msg(hapd->msg_ctx, MSG_DEBUG,
5902                                  "handle_disassoc - too short payload (len=%lu)",
5903                                  (unsigned long) len);
5904                     return;
5905           }
5906 
5907           sta = ap_get_sta(hapd, mgmt->sa);
5908           if (!sta) {
5909                     wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR
5910                               " trying to disassociate, but it is not associated",
5911                               MAC2STR(mgmt->sa));
5912                     return;
5913           }
5914 
5915           if (hostapd_ml_handle_disconnect(hapd, sta, mgmt, true))
5916                     return;
5917 
5918           hostapd_disassoc_sta(hapd, sta, mgmt);
5919 }
5920 
5921 
handle_deauth(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len)5922 static void handle_deauth(struct hostapd_data *hapd,
5923                                 const struct ieee80211_mgmt *mgmt, size_t len)
5924 {
5925           struct sta_info *sta;
5926 
5927           if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.deauth)) {
5928                     wpa_msg(hapd->msg_ctx, MSG_DEBUG,
5929                               "handle_deauth - too short payload (len=%lu)",
5930                               (unsigned long) len);
5931                     return;
5932           }
5933 
5934           /* Clear the PTKSA cache entries for PASN */
5935           ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE);
5936 
5937           sta = ap_get_sta(hapd, mgmt->sa);
5938           if (!sta) {
5939                     wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR
5940                               " trying to deauthenticate, but it is not authenticated",
5941                               MAC2STR(mgmt->sa));
5942                     return;
5943           }
5944 
5945           if (hostapd_ml_handle_disconnect(hapd, sta, mgmt, false))
5946                     return;
5947 
5948           hostapd_deauth_sta(hapd, sta, mgmt);
5949 }
5950 
5951 
handle_beacon(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len,struct hostapd_frame_info * fi)5952 static void handle_beacon(struct hostapd_data *hapd,
5953                                 const struct ieee80211_mgmt *mgmt, size_t len,
5954                                 struct hostapd_frame_info *fi)
5955 {
5956           struct ieee802_11_elems elems;
5957 
5958           if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.beacon)) {
5959                     wpa_printf(MSG_INFO, "handle_beacon - too short payload (len=%lu)",
5960                                  (unsigned long) len);
5961                     return;
5962           }
5963 
5964           (void) ieee802_11_parse_elems(mgmt->u.beacon.variable,
5965                                               len - (IEEE80211_HDRLEN +
5966                                                        sizeof(mgmt->u.beacon)), &elems,
5967                                               0);
5968 
5969           ap_list_process_beacon(hapd->iface, mgmt, &elems, fi);
5970 }
5971 
5972 
robust_action_frame(u8 category)5973 static int robust_action_frame(u8 category)
5974 {
5975           return category != WLAN_ACTION_PUBLIC &&
5976                     category != WLAN_ACTION_HT;
5977 }
5978 
5979 
handle_action(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len,unsigned int freq)5980 static int handle_action(struct hostapd_data *hapd,
5981                                const struct ieee80211_mgmt *mgmt, size_t len,
5982                                unsigned int freq)
5983 {
5984           struct sta_info *sta;
5985           u8 *action __maybe_unused;
5986 
5987           if (len < IEEE80211_HDRLEN + 2 + 1) {
5988                     hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
5989                                      HOSTAPD_LEVEL_DEBUG,
5990                                      "handle_action - too short payload (len=%lu)",
5991                                      (unsigned long) len);
5992                     return 0;
5993           }
5994 
5995           action = (u8 *) &mgmt->u.action.u;
5996           wpa_printf(MSG_DEBUG, "RX_ACTION category %u action %u sa " MACSTR
5997                        " da " MACSTR " len %d freq %u",
5998                        mgmt->u.action.category, *action,
5999                        MAC2STR(mgmt->sa), MAC2STR(mgmt->da), (int) len, freq);
6000 
6001           sta = ap_get_sta(hapd, mgmt->sa);
6002 
6003           if (mgmt->u.action.category != WLAN_ACTION_PUBLIC &&
6004               (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))) {
6005                     wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignored Action "
6006                                  "frame (category=%u) from unassociated STA " MACSTR,
6007                                  mgmt->u.action.category, MAC2STR(mgmt->sa));
6008                     return 0;
6009           }
6010 
6011           if (sta && (sta->flags & WLAN_STA_MFP) &&
6012               !(mgmt->frame_control & host_to_le16(WLAN_FC_ISWEP)) &&
6013               robust_action_frame(mgmt->u.action.category)) {
6014                     hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
6015                                      HOSTAPD_LEVEL_DEBUG,
6016                                      "Dropped unprotected Robust Action frame from "
6017                                      "an MFP STA");
6018                     return 0;
6019           }
6020 
6021           if (sta) {
6022                     u16 fc = le_to_host16(mgmt->frame_control);
6023                     u16 seq_ctrl = le_to_host16(mgmt->seq_ctrl);
6024 
6025                     if ((fc & WLAN_FC_RETRY) &&
6026                         sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
6027                         sta->last_seq_ctrl == seq_ctrl &&
6028                         sta->last_subtype == WLAN_FC_STYPE_ACTION) {
6029                               hostapd_logger(hapd, sta->addr,
6030                                                HOSTAPD_MODULE_IEEE80211,
6031                                                HOSTAPD_LEVEL_DEBUG,
6032                                                "Drop repeated action frame seq_ctrl=0x%x",
6033                                                seq_ctrl);
6034                               return 1;
6035                     }
6036 
6037                     sta->last_seq_ctrl = seq_ctrl;
6038                     sta->last_subtype = WLAN_FC_STYPE_ACTION;
6039           }
6040 
6041           switch (mgmt->u.action.category) {
6042 #ifdef CONFIG_IEEE80211R_AP
6043           case WLAN_ACTION_FT:
6044                     if (!sta ||
6045                         wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action,
6046                                              len - IEEE80211_HDRLEN))
6047                               break;
6048                     return 1;
6049 #endif /* CONFIG_IEEE80211R_AP */
6050           case WLAN_ACTION_WMM:
6051                     hostapd_wmm_action(hapd, mgmt, len);
6052                     return 1;
6053           case WLAN_ACTION_SA_QUERY:
6054                     ieee802_11_sa_query_action(hapd, mgmt, len);
6055                     return 1;
6056 #ifdef CONFIG_WNM_AP
6057           case WLAN_ACTION_WNM:
6058                     ieee802_11_rx_wnm_action_ap(hapd, mgmt, len);
6059                     return 1;
6060 #endif /* CONFIG_WNM_AP */
6061 #ifdef CONFIG_FST
6062           case WLAN_ACTION_FST:
6063                     if (hapd->iface->fst)
6064                               fst_rx_action(hapd->iface->fst, mgmt, len);
6065                     else
6066                               wpa_printf(MSG_DEBUG,
6067                                            "FST: Ignore FST Action frame - no FST attached");
6068                     return 1;
6069 #endif /* CONFIG_FST */
6070           case WLAN_ACTION_PUBLIC:
6071           case WLAN_ACTION_PROTECTED_DUAL:
6072                     if (len >= IEEE80211_HDRLEN + 2 &&
6073                         mgmt->u.action.u.public_action.action ==
6074                         WLAN_PA_20_40_BSS_COEX) {
6075                               hostapd_2040_coex_action(hapd, mgmt, len);
6076                               return 1;
6077                     }
6078 #ifdef CONFIG_DPP
6079                     if (len >= IEEE80211_HDRLEN + 6 &&
6080                         mgmt->u.action.u.vs_public_action.action ==
6081                         WLAN_PA_VENDOR_SPECIFIC &&
6082                         WPA_GET_BE24(mgmt->u.action.u.vs_public_action.oui) ==
6083                         OUI_WFA &&
6084                         mgmt->u.action.u.vs_public_action.variable[0] ==
6085                         DPP_OUI_TYPE) {
6086                               const u8 *pos, *end;
6087 
6088                               pos = mgmt->u.action.u.vs_public_action.oui;
6089                               end = ((const u8 *) mgmt) + len;
6090                               hostapd_dpp_rx_action(hapd, mgmt->sa, pos, end - pos,
6091                                                         freq);
6092                               return 1;
6093                     }
6094                     if (len >= IEEE80211_HDRLEN + 2 &&
6095                         (mgmt->u.action.u.public_action.action ==
6096                          WLAN_PA_GAS_INITIAL_RESP ||
6097                          mgmt->u.action.u.public_action.action ==
6098                          WLAN_PA_GAS_COMEBACK_RESP)) {
6099                               const u8 *pos, *end;
6100 
6101                               pos = &mgmt->u.action.u.public_action.action;
6102                               end = ((const u8 *) mgmt) + len;
6103                               if (gas_query_ap_rx(hapd->gas, mgmt->sa,
6104                                                       mgmt->u.action.category,
6105                                                       pos, end - pos, freq) == 0)
6106                                         return 1;
6107                     }
6108 #endif /* CONFIG_DPP */
6109 #ifdef CONFIG_NAN_USD
6110                     if (mgmt->u.action.category == WLAN_ACTION_PUBLIC &&
6111                         len >= IEEE80211_HDRLEN + 5 &&
6112                         mgmt->u.action.u.vs_public_action.action ==
6113                         WLAN_PA_VENDOR_SPECIFIC &&
6114                         WPA_GET_BE24(mgmt->u.action.u.vs_public_action.oui) ==
6115                         OUI_WFA &&
6116                         mgmt->u.action.u.vs_public_action.variable[0] ==
6117                         NAN_OUI_TYPE) {
6118                               const u8 *pos, *end;
6119 
6120                               pos = mgmt->u.action.u.vs_public_action.variable;
6121                               end = ((const u8 *) mgmt) + len;
6122                               pos++;
6123                               hostapd_nan_usd_rx_sdf(hapd, mgmt->sa, freq,
6124                                                          pos, end - pos);
6125                               return 1;
6126                     }
6127 #endif /* CONFIG_NAN_USD */
6128                     if (hapd->public_action_cb) {
6129                               hapd->public_action_cb(hapd->public_action_cb_ctx,
6130                                                          (u8 *) mgmt, len, freq);
6131                     }
6132                     if (hapd->public_action_cb2) {
6133                               hapd->public_action_cb2(hapd->public_action_cb2_ctx,
6134                                                             (u8 *) mgmt, len, freq);
6135                     }
6136                     if (hapd->public_action_cb || hapd->public_action_cb2)
6137                               return 1;
6138                     break;
6139           case WLAN_ACTION_VENDOR_SPECIFIC:
6140                     if (hapd->vendor_action_cb) {
6141                               if (hapd->vendor_action_cb(hapd->vendor_action_cb_ctx,
6142                                                                (u8 *) mgmt, len, freq) == 0)
6143                                         return 1;
6144                     }
6145                     break;
6146 #ifndef CONFIG_NO_RRM
6147           case WLAN_ACTION_RADIO_MEASUREMENT:
6148                     hostapd_handle_radio_measurement(hapd, (const u8 *) mgmt, len);
6149                     return 1;
6150 #endif /* CONFIG_NO_RRM */
6151           }
6152 
6153           hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
6154                            HOSTAPD_LEVEL_DEBUG,
6155                            "handle_action - unknown action category %d or invalid "
6156                            "frame",
6157                            mgmt->u.action.category);
6158           if (!is_multicast_ether_addr(mgmt->da) &&
6159               !(mgmt->u.action.category & 0x80) &&
6160               !is_multicast_ether_addr(mgmt->sa)) {
6161                     struct ieee80211_mgmt *resp;
6162 
6163                     /*
6164                      * IEEE 802.11-REVma/D9.0 - 7.3.1.11
6165                      * Return the Action frame to the source without change
6166                      * except that MSB of the Category set to 1.
6167                      */
6168                     wpa_printf(MSG_DEBUG, "IEEE 802.11: Return unknown Action "
6169                                  "frame back to sender");
6170                     resp = os_memdup(mgmt, len);
6171                     if (resp == NULL)
6172                               return 0;
6173                     os_memcpy(resp->da, resp->sa, ETH_ALEN);
6174                     os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
6175                     os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
6176                     resp->u.action.category |= 0x80;
6177 
6178                     if (hostapd_drv_send_mlme(hapd, resp, len, 0, NULL, 0, 0) < 0) {
6179                               wpa_printf(MSG_ERROR, "IEEE 802.11: Failed to send "
6180                                            "Action frame");
6181                     }
6182                     os_free(resp);
6183           }
6184 
6185           return 1;
6186 }
6187 
6188 
6189 /**
6190  * notify_mgmt_frame - Notify of Management frames on the control interface
6191  * @hapd: hostapd BSS data structure (the BSS to which the Management frame was
6192  * sent to)
6193  * @buf: Management frame data (starting from the IEEE 802.11 header)
6194  * @len: Length of frame data in octets
6195  *
6196  * Notify the control interface of any received Management frame.
6197  */
notify_mgmt_frame(struct hostapd_data * hapd,const u8 * buf,size_t len)6198 static void notify_mgmt_frame(struct hostapd_data *hapd, const u8 *buf,
6199                                     size_t len)
6200 {
6201 
6202           int hex_len = len * 2 + 1;
6203           char *hex = os_malloc(hex_len);
6204 
6205           if (hex) {
6206                     wpa_snprintf_hex(hex, hex_len, buf, len);
6207                     wpa_msg_ctrl(hapd->msg_ctx, MSG_INFO,
6208                                    AP_MGMT_FRAME_RECEIVED "buf=%s", hex);
6209                     os_free(hex);
6210           }
6211 }
6212 
6213 
6214 /**
6215  * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
6216  * @hapd: hostapd BSS data structure (the BSS to which the management frame was
6217  * sent to)
6218  * @buf: management frame data (starting from IEEE 802.11 header)
6219  * @len: length of frame data in octets
6220  * @fi: meta data about received frame (signal level, etc.)
6221  *
6222  * Process all incoming IEEE 802.11 management frames. This will be called for
6223  * each frame received from the kernel driver through wlan#ap interface. In
6224  * addition, it can be called to re-inserted pending frames (e.g., when using
6225  * external RADIUS server as an MAC ACL).
6226  */
ieee802_11_mgmt(struct hostapd_data * hapd,const u8 * buf,size_t len,struct hostapd_frame_info * fi)6227 int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
6228                         struct hostapd_frame_info *fi)
6229 {
6230           struct ieee80211_mgmt *mgmt;
6231           u16 fc, stype;
6232           int ret = 0;
6233           unsigned int freq;
6234           int ssi_signal = fi ? fi->ssi_signal : 0;
6235 #ifdef CONFIG_NAN_USD
6236           static const u8 nan_network_id[ETH_ALEN] =
6237                     { 0x51, 0x6f, 0x9a, 0x01, 0x00, 0x00 };
6238 #endif /* CONFIG_NAN_USD */
6239 
6240           if (len < 24)
6241                     return 0;
6242 
6243           if (fi && fi->freq)
6244                     freq = fi->freq;
6245           else
6246                     freq = hapd->iface->freq;
6247 
6248           mgmt = (struct ieee80211_mgmt *) buf;
6249           fc = le_to_host16(mgmt->frame_control);
6250           stype = WLAN_FC_GET_STYPE(fc);
6251 
6252           if (is_multicast_ether_addr(mgmt->sa) ||
6253               is_zero_ether_addr(mgmt->sa) ||
6254               ether_addr_equal(mgmt->sa, hapd->own_addr)) {
6255                     /* Do not process any frames with unexpected/invalid SA so that
6256                      * we do not add any state for unexpected STA addresses or end
6257                      * up sending out frames to unexpected destination. */
6258                     wpa_printf(MSG_DEBUG, "MGMT: Invalid SA=" MACSTR
6259                                  " in received frame - ignore this frame silently",
6260                                  MAC2STR(mgmt->sa));
6261                     return 0;
6262           }
6263 
6264           if (stype == WLAN_FC_STYPE_BEACON) {
6265                     handle_beacon(hapd, mgmt, len, fi);
6266                     return 1;
6267           }
6268 
6269           if (!is_broadcast_ether_addr(mgmt->bssid) &&
6270 #ifdef CONFIG_P2P
6271               /* Invitation responses can be sent with the peer MAC as BSSID */
6272               !((hapd->conf->p2p & P2P_GROUP_OWNER) &&
6273                 stype == WLAN_FC_STYPE_ACTION) &&
6274 #endif /* CONFIG_P2P */
6275 #ifdef CONFIG_MESH
6276               !(hapd->conf->mesh & MESH_ENABLED) &&
6277 #endif /* CONFIG_MESH */
6278 #ifdef CONFIG_IEEE80211BE
6279               !(hapd->conf->mld_ap &&
6280                 ether_addr_equal(hapd->mld->mld_addr, mgmt->bssid)) &&
6281 #endif /* CONFIG_IEEE80211BE */
6282               !ether_addr_equal(mgmt->bssid, hapd->own_addr)) {
6283                     wpa_printf(MSG_INFO, "MGMT: BSSID=" MACSTR " not our address",
6284                                  MAC2STR(mgmt->bssid));
6285                     return 0;
6286           }
6287 
6288           if (hapd->iface->state != HAPD_IFACE_ENABLED) {
6289                     wpa_printf(MSG_DEBUG, "MGMT: Ignore management frame while interface is not enabled (SA=" MACSTR " DA=" MACSTR " subtype=%u)",
6290                                  MAC2STR(mgmt->sa), MAC2STR(mgmt->da), stype);
6291                     return 1;
6292           }
6293 
6294           if (stype == WLAN_FC_STYPE_PROBE_REQ) {
6295                     handle_probe_req(hapd, mgmt, len, ssi_signal);
6296                     return 1;
6297           }
6298 
6299           if ((!is_broadcast_ether_addr(mgmt->da) ||
6300                stype != WLAN_FC_STYPE_ACTION) &&
6301 #ifdef CONFIG_IEEE80211BE
6302               !(hapd->conf->mld_ap &&
6303                 ether_addr_equal(hapd->mld->mld_addr, mgmt->bssid)) &&
6304 #endif /* CONFIG_IEEE80211BE */
6305 #ifdef CONFIG_NAN_USD
6306               !ether_addr_equal(mgmt->da, nan_network_id) &&
6307 #endif /* CONFIG_NAN_USD */
6308               !ether_addr_equal(mgmt->da, hapd->own_addr)) {
6309                     hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
6310                                      HOSTAPD_LEVEL_DEBUG,
6311                                      "MGMT: DA=" MACSTR " not our address",
6312                                      MAC2STR(mgmt->da));
6313                     return 0;
6314           }
6315 
6316           if (hapd->iconf->track_sta_max_num)
6317                     sta_track_add(hapd->iface, mgmt->sa, ssi_signal);
6318 
6319           if (hapd->conf->notify_mgmt_frames)
6320                     notify_mgmt_frame(hapd, buf, len);
6321 
6322           switch (stype) {
6323           case WLAN_FC_STYPE_AUTH:
6324                     wpa_printf(MSG_DEBUG, "mgmt::auth");
6325                     handle_auth(hapd, mgmt, len, ssi_signal, 0);
6326                     ret = 1;
6327                     break;
6328           case WLAN_FC_STYPE_ASSOC_REQ:
6329                     wpa_printf(MSG_DEBUG, "mgmt::assoc_req");
6330                     handle_assoc(hapd, mgmt, len, 0, ssi_signal);
6331                     ret = 1;
6332                     break;
6333           case WLAN_FC_STYPE_REASSOC_REQ:
6334                     wpa_printf(MSG_DEBUG, "mgmt::reassoc_req");
6335                     handle_assoc(hapd, mgmt, len, 1, ssi_signal);
6336                     ret = 1;
6337                     break;
6338           case WLAN_FC_STYPE_DISASSOC:
6339                     wpa_printf(MSG_DEBUG, "mgmt::disassoc");
6340                     handle_disassoc(hapd, mgmt, len);
6341                     ret = 1;
6342                     break;
6343           case WLAN_FC_STYPE_DEAUTH:
6344                     wpa_msg(hapd->msg_ctx, MSG_DEBUG, "mgmt::deauth");
6345                     handle_deauth(hapd, mgmt, len);
6346                     ret = 1;
6347                     break;
6348           case WLAN_FC_STYPE_ACTION:
6349                     wpa_printf(MSG_DEBUG, "mgmt::action");
6350                     ret = handle_action(hapd, mgmt, len, freq);
6351                     break;
6352           default:
6353                     hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
6354                                      HOSTAPD_LEVEL_DEBUG,
6355                                      "unknown mgmt frame subtype %d", stype);
6356                     break;
6357           }
6358 
6359           return ret;
6360 }
6361 
6362 
handle_auth_cb(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len,int ok)6363 static void handle_auth_cb(struct hostapd_data *hapd,
6364                                  const struct ieee80211_mgmt *mgmt,
6365                                  size_t len, int ok)
6366 {
6367           u16 auth_alg, auth_transaction, status_code;
6368           struct sta_info *sta;
6369           bool success_status;
6370 
6371           sta = ap_get_sta(hapd, mgmt->da);
6372           if (!sta) {
6373                     wpa_printf(MSG_DEBUG, "handle_auth_cb: STA " MACSTR
6374                                  " not found",
6375                                  MAC2STR(mgmt->da));
6376                     return;
6377           }
6378 
6379           if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
6380                     wpa_printf(MSG_INFO, "handle_auth_cb - too short payload (len=%lu)",
6381                                  (unsigned long) len);
6382                     auth_alg = 0;
6383                     auth_transaction = 0;
6384                     status_code = WLAN_STATUS_UNSPECIFIED_FAILURE;
6385                     goto fail;
6386           }
6387 
6388           auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
6389           auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
6390           status_code = le_to_host16(mgmt->u.auth.status_code);
6391 
6392           if (!ok) {
6393                     hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
6394                                      HOSTAPD_LEVEL_NOTICE,
6395                                      "did not acknowledge authentication response");
6396                     goto fail;
6397           }
6398 
6399           if (status_code == WLAN_STATUS_SUCCESS &&
6400               ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) ||
6401                (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) {
6402                     hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
6403                                      HOSTAPD_LEVEL_INFO, "authenticated");
6404                     sta->flags |= WLAN_STA_AUTH;
6405                     if (sta->added_unassoc)
6406                               hostapd_set_sta_flags(hapd, sta);
6407                     return;
6408           }
6409 
6410 fail:
6411           success_status = status_code == WLAN_STATUS_SUCCESS;
6412 #ifdef CONFIG_SAE
6413           if (auth_alg == WLAN_AUTH_SAE && auth_transaction == 1)
6414                     success_status = sae_status_success(hapd, status_code);
6415 #endif /* CONFIG_SAE */
6416           if (!success_status && sta->added_unassoc) {
6417                     hostapd_drv_sta_remove(hapd, sta->addr);
6418                     sta->added_unassoc = 0;
6419           }
6420 }
6421 
6422 
hostapd_set_wds_encryption(struct hostapd_data * hapd,struct sta_info * sta,char * ifname_wds)6423 static void hostapd_set_wds_encryption(struct hostapd_data *hapd,
6424                                                struct sta_info *sta,
6425                                                char *ifname_wds)
6426 {
6427 #ifdef CONFIG_WEP
6428           int i;
6429           struct hostapd_ssid *ssid = &hapd->conf->ssid;
6430 
6431           if (hapd->conf->ieee802_1x || hapd->conf->wpa)
6432                     return;
6433 
6434           for (i = 0; i < 4; i++) {
6435                     if (ssid->wep.key[i] &&
6436                         hostapd_drv_set_key(ifname_wds, hapd, WPA_ALG_WEP, NULL, i,
6437                                                   0, i == ssid->wep.idx, NULL, 0,
6438                                                   ssid->wep.key[i], ssid->wep.len[i],
6439                                                   i == ssid->wep.idx ?
6440                                                   KEY_FLAG_GROUP_RX_TX_DEFAULT :
6441                                                   KEY_FLAG_GROUP_RX_TX)) {
6442                               wpa_printf(MSG_WARNING,
6443                                            "Could not set WEP keys for WDS interface; %s",
6444                                            ifname_wds);
6445                               break;
6446                     }
6447           }
6448 #endif /* CONFIG_WEP */
6449 }
6450 
6451 
6452 #ifdef CONFIG_IEEE80211BE
ieee80211_ml_link_sta_assoc_cb(struct hostapd_data * hapd,struct sta_info * sta,struct mld_link_info * link,bool ok)6453 static void ieee80211_ml_link_sta_assoc_cb(struct hostapd_data *hapd,
6454                                                      struct sta_info *sta,
6455                                                      struct mld_link_info *link,
6456                                                      bool ok)
6457 {
6458           bool updated = false;
6459 
6460           if (!ok) {
6461                     hostapd_logger(hapd, link->peer_addr, HOSTAPD_MODULE_IEEE80211,
6462                                      HOSTAPD_LEVEL_DEBUG,
6463                                      "did not acknowledge association response");
6464                     sta->flags &= ~WLAN_STA_ASSOC_REQ_OK;
6465 
6466                     /* The STA is added only in case of SUCCESS */
6467                     if (link->status == WLAN_STATUS_SUCCESS)
6468                               hostapd_drv_sta_remove(hapd, sta->addr);
6469 
6470                     return;
6471           }
6472 
6473           if (link->status != WLAN_STATUS_SUCCESS)
6474                     return;
6475 
6476           sta->flags |= WLAN_STA_ASSOC;
6477           sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE;
6478 
6479           if (!hapd->conf->ieee802_1x && !hapd->conf->wpa)
6480                     updated = ap_sta_set_authorized_flag(hapd, sta, 1);
6481 
6482           hostapd_set_sta_flags(hapd, sta);
6483           if (updated)
6484                     ap_sta_set_authorized_event(hapd, sta, 1);
6485 
6486           /*
6487            * TODOs:
6488            * - IEEE 802.1X port enablement is not needed as done on the station
6489            *     doing the connection.
6490            * - Not handling accounting
6491            * - Need to handle VLAN configuration
6492            */
6493 }
6494 #endif /* CONFIG_IEEE80211BE */
6495 
6496 
hostapd_ml_handle_assoc_cb(struct hostapd_data * hapd,struct sta_info * sta,bool ok)6497 static void hostapd_ml_handle_assoc_cb(struct hostapd_data *hapd,
6498                                                struct sta_info *sta, bool ok)
6499 {
6500 #ifdef CONFIG_IEEE80211BE
6501           struct hostapd_data *tmp_hapd;
6502 
6503           if (!hostapd_is_mld_ap(hapd))
6504                     return;
6505 
6506           for_each_mld_link(tmp_hapd, hapd) {
6507                     struct mld_link_info *link;
6508                     struct sta_info *tmp_sta;
6509 
6510                     if (tmp_hapd == hapd)
6511                               continue;
6512 
6513                     link = &sta->mld_info.links[tmp_hapd->mld_link_id];
6514                     if (!link->valid)
6515                               continue;
6516 
6517                     for (tmp_sta = tmp_hapd->sta_list; tmp_sta;
6518                          tmp_sta = tmp_sta->next) {
6519                               if (tmp_sta == sta ||
6520                                   tmp_sta->mld_assoc_link_id !=
6521                                   sta->mld_assoc_link_id ||
6522                                   tmp_sta->aid != sta->aid)
6523                                         continue;
6524 
6525                               ieee80211_ml_link_sta_assoc_cb(tmp_hapd, tmp_sta, link,
6526                                                                    ok);
6527                               break;
6528                     }
6529           }
6530 #endif /* CONFIG_IEEE80211BE */
6531 }
6532 
6533 
handle_assoc_cb(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len,int reassoc,int ok)6534 static void handle_assoc_cb(struct hostapd_data *hapd,
6535                                   const struct ieee80211_mgmt *mgmt,
6536                                   size_t len, int reassoc, int ok)
6537 {
6538           u16 status;
6539           struct sta_info *sta;
6540           int new_assoc = 1;
6541 
6542           sta = ap_get_sta(hapd, mgmt->da);
6543           if (!sta) {
6544                     wpa_printf(MSG_INFO, "handle_assoc_cb: STA " MACSTR " not found",
6545                                  MAC2STR(mgmt->da));
6546                     return;
6547           }
6548 
6549 #ifdef CONFIG_IEEE80211BE
6550           if (ap_sta_is_mld(hapd, sta) &&
6551               hapd->mld_link_id != sta->mld_assoc_link_id) {
6552                     /* See ieee80211_ml_link_sta_assoc_cb() for the MLD case */
6553                     wpa_printf(MSG_DEBUG,
6554                                  "%s: MLD: ignore on link station (%d != %d)",
6555                                  __func__, hapd->mld_link_id, sta->mld_assoc_link_id);
6556                     return;
6557           }
6558 #endif /* CONFIG_IEEE80211BE */
6559 
6560           if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) :
6561                                               sizeof(mgmt->u.assoc_resp))) {
6562                     wpa_printf(MSG_INFO,
6563                                  "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)",
6564                                  reassoc, (unsigned long) len);
6565                     hostapd_drv_sta_remove(hapd, sta->addr);
6566                     return;
6567           }
6568 
6569           if (reassoc)
6570                     status = le_to_host16(mgmt->u.reassoc_resp.status_code);
6571           else
6572                     status = le_to_host16(mgmt->u.assoc_resp.status_code);
6573 
6574           if (!ok) {
6575                     hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
6576                                      HOSTAPD_LEVEL_DEBUG,
6577                                      "did not acknowledge association response");
6578                     sta->flags &= ~WLAN_STA_ASSOC_REQ_OK;
6579                     /* The STA is added only in case of SUCCESS */
6580                     if (status == WLAN_STATUS_SUCCESS)
6581                               hostapd_drv_sta_remove(hapd, sta->addr);
6582 
6583                     goto handle_ml;
6584           }
6585 
6586           if (status != WLAN_STATUS_SUCCESS)
6587                     goto handle_ml;
6588 
6589           /* Stop previous accounting session, if one is started, and allocate
6590            * new session id for the new session. */
6591           accounting_sta_stop(hapd, sta);
6592 
6593           hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
6594                            HOSTAPD_LEVEL_INFO,
6595                            "associated (aid %d)",
6596                            sta->aid);
6597 
6598           if (sta->flags & WLAN_STA_ASSOC)
6599                     new_assoc = 0;
6600           sta->flags |= WLAN_STA_ASSOC;
6601           sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE;
6602           if ((!hapd->conf->ieee802_1x && !hapd->conf->wpa &&
6603                !hapd->conf->osen) ||
6604               sta->auth_alg == WLAN_AUTH_FILS_SK ||
6605               sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
6606               sta->auth_alg == WLAN_AUTH_FILS_PK ||
6607               sta->auth_alg == WLAN_AUTH_FT) {
6608                     /*
6609                      * Open, static WEP, FT protocol, or FILS; no separate
6610                      * authorization step.
6611                      */
6612                     ap_sta_set_authorized(hapd, sta, 1);
6613           }
6614 
6615           if (reassoc)
6616                     mlme_reassociate_indication(hapd, sta);
6617           else
6618                     mlme_associate_indication(hapd, sta);
6619 
6620           sta->sa_query_timed_out = 0;
6621 
6622           if (sta->eapol_sm == NULL) {
6623                     /*
6624                      * This STA does not use RADIUS server for EAP authentication,
6625                      * so bind it to the selected VLAN interface now, since the
6626                      * interface selection is not going to change anymore.
6627                      */
6628                     if (ap_sta_bind_vlan(hapd, sta) < 0)
6629                               goto handle_ml;
6630           } else if (sta->vlan_id) {
6631                     /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
6632                     if (ap_sta_bind_vlan(hapd, sta) < 0)
6633                               goto handle_ml;
6634           }
6635 
6636           hostapd_set_sta_flags(hapd, sta);
6637 
6638           if (!(sta->flags & WLAN_STA_WDS) && sta->pending_wds_enable) {
6639                     wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for STA "
6640                                  MACSTR " based on pending request",
6641                                  MAC2STR(sta->addr));
6642                     sta->pending_wds_enable = 0;
6643                     sta->flags |= WLAN_STA_WDS;
6644           }
6645 
6646           /* WPS not supported on backhaul BSS. Disable 4addr mode on fronthaul */
6647           if ((sta->flags & WLAN_STA_WDS) ||
6648               (sta->flags & WLAN_STA_MULTI_AP &&
6649                (hapd->conf->multi_ap & BACKHAUL_BSS) &&
6650                hapd->conf->wds_sta &&
6651                !(sta->flags & WLAN_STA_WPS))) {
6652                     int ret;
6653                     char ifname_wds[IFNAMSIZ + 1];
6654 
6655                     wpa_printf(MSG_DEBUG, "Reenable 4-address WDS mode for STA "
6656                                  MACSTR " (aid %u)",
6657                                  MAC2STR(sta->addr), sta->aid);
6658                     ret = hostapd_set_wds_sta(hapd, ifname_wds, sta->addr,
6659                                                     sta->aid, 1);
6660                     if (!ret)
6661                               hostapd_set_wds_encryption(hapd, sta, ifname_wds);
6662           }
6663 
6664           if (sta->auth_alg == WLAN_AUTH_FT)
6665                     wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT);
6666           else
6667                     wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
6668           hapd->new_assoc_sta_cb(hapd, sta, !new_assoc);
6669           ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
6670 
6671 #ifdef CONFIG_FILS
6672           if ((sta->auth_alg == WLAN_AUTH_FILS_SK ||
6673                sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
6674                sta->auth_alg == WLAN_AUTH_FILS_PK) &&
6675               fils_set_tk(sta->wpa_sm) < 0) {
6676                     wpa_printf(MSG_DEBUG, "FILS: TK configuration failed");
6677                     ap_sta_disconnect(hapd, sta, sta->addr,
6678                                           WLAN_REASON_UNSPECIFIED);
6679                     return;
6680           }
6681 #endif /* CONFIG_FILS */
6682 
6683           if (sta->pending_eapol_rx) {
6684                     struct os_reltime now, age;
6685 
6686                     os_get_reltime(&now);
6687                     os_reltime_sub(&now, &sta->pending_eapol_rx->rx_time, &age);
6688                     if (age.sec == 0 && age.usec < 200000) {
6689                               wpa_printf(MSG_DEBUG,
6690                                            "Process pending EAPOL frame that was received from " MACSTR " just before association notification",
6691                                            MAC2STR(sta->addr));
6692                               ieee802_1x_receive(
6693                                         hapd, mgmt->da,
6694                                         wpabuf_head(sta->pending_eapol_rx->buf),
6695                                         wpabuf_len(sta->pending_eapol_rx->buf),
6696                                         sta->pending_eapol_rx->encrypted);
6697                     }
6698                     wpabuf_free(sta->pending_eapol_rx->buf);
6699                     os_free(sta->pending_eapol_rx);
6700                     sta->pending_eapol_rx = NULL;
6701           }
6702 
6703 handle_ml:
6704           hostapd_ml_handle_assoc_cb(hapd, sta, ok);
6705 }
6706 
6707 
handle_deauth_cb(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len,int ok)6708 static void handle_deauth_cb(struct hostapd_data *hapd,
6709                                    const struct ieee80211_mgmt *mgmt,
6710                                    size_t len, int ok)
6711 {
6712           struct sta_info *sta;
6713           if (is_multicast_ether_addr(mgmt->da))
6714                     return;
6715           sta = ap_get_sta(hapd, mgmt->da);
6716           if (!sta) {
6717                     wpa_printf(MSG_DEBUG, "handle_deauth_cb: STA " MACSTR
6718                                  " not found", MAC2STR(mgmt->da));
6719                     return;
6720           }
6721           if (ok)
6722                     wpa_printf(MSG_DEBUG, "STA " MACSTR " acknowledged deauth",
6723                                  MAC2STR(sta->addr));
6724           else
6725                     wpa_printf(MSG_DEBUG, "STA " MACSTR " did not acknowledge "
6726                                  "deauth", MAC2STR(sta->addr));
6727 
6728           ap_sta_deauth_cb(hapd, sta);
6729 }
6730 
6731 
handle_disassoc_cb(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len,int ok)6732 static void handle_disassoc_cb(struct hostapd_data *hapd,
6733                                      const struct ieee80211_mgmt *mgmt,
6734                                      size_t len, int ok)
6735 {
6736           struct sta_info *sta;
6737           if (is_multicast_ether_addr(mgmt->da))
6738                     return;
6739           sta = ap_get_sta(hapd, mgmt->da);
6740           if (!sta) {
6741                     wpa_printf(MSG_DEBUG, "handle_disassoc_cb: STA " MACSTR
6742                                  " not found", MAC2STR(mgmt->da));
6743                     return;
6744           }
6745           if (ok)
6746                     wpa_printf(MSG_DEBUG, "STA " MACSTR " acknowledged disassoc",
6747                                  MAC2STR(sta->addr));
6748           else
6749                     wpa_printf(MSG_DEBUG, "STA " MACSTR " did not acknowledge "
6750                                  "disassoc", MAC2STR(sta->addr));
6751 
6752           ap_sta_disassoc_cb(hapd, sta);
6753 }
6754 
6755 
handle_action_cb(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len,int ok)6756 static void handle_action_cb(struct hostapd_data *hapd,
6757                                    const struct ieee80211_mgmt *mgmt,
6758                                    size_t len, int ok)
6759 {
6760           struct sta_info *sta;
6761 #ifndef CONFIG_NO_RRM
6762           const struct rrm_measurement_report_element *report;
6763 #endif /* CONFIG_NO_RRM */
6764 
6765 #ifdef CONFIG_DPP
6766           if (len >= IEEE80211_HDRLEN + 6 &&
6767               mgmt->u.action.category == WLAN_ACTION_PUBLIC &&
6768               mgmt->u.action.u.vs_public_action.action ==
6769               WLAN_PA_VENDOR_SPECIFIC &&
6770               WPA_GET_BE24(mgmt->u.action.u.vs_public_action.oui) ==
6771               OUI_WFA &&
6772               mgmt->u.action.u.vs_public_action.variable[0] ==
6773               DPP_OUI_TYPE) {
6774                     const u8 *pos, *end;
6775 
6776                     pos = &mgmt->u.action.u.vs_public_action.variable[1];
6777                     end = ((const u8 *) mgmt) + len;
6778                     hostapd_dpp_tx_status(hapd, mgmt->da, pos, end - pos, ok);
6779                     return;
6780           }
6781           if (len >= IEEE80211_HDRLEN + 2 &&
6782               mgmt->u.action.category == WLAN_ACTION_PUBLIC &&
6783               (mgmt->u.action.u.public_action.action ==
6784                WLAN_PA_GAS_INITIAL_REQ ||
6785                mgmt->u.action.u.public_action.action ==
6786                WLAN_PA_GAS_COMEBACK_REQ)) {
6787                     const u8 *pos, *end;
6788 
6789                     pos = mgmt->u.action.u.public_action.variable;
6790                     end = ((const u8 *) mgmt) + len;
6791                     gas_query_ap_tx_status(hapd->gas, mgmt->da, pos, end - pos, ok);
6792                     return;
6793           }
6794 #endif /* CONFIG_DPP */
6795           if (is_multicast_ether_addr(mgmt->da))
6796                     return;
6797           sta = ap_get_sta(hapd, mgmt->da);
6798           if (!sta) {
6799                     wpa_printf(MSG_DEBUG, "handle_action_cb: STA " MACSTR
6800                                  " not found", MAC2STR(mgmt->da));
6801                     return;
6802           }
6803 
6804 #ifdef CONFIG_HS20
6805           if (ok && len >= IEEE80211_HDRLEN + 2 &&
6806               mgmt->u.action.category == WLAN_ACTION_WNM &&
6807               mgmt->u.action.u.vs_public_action.action == WNM_NOTIFICATION_REQ &&
6808               sta->hs20_deauth_on_ack) {
6809                     wpa_printf(MSG_DEBUG, "HS 2.0: Deauthenticate STA " MACSTR
6810                                  " on acknowledging the WNM-Notification",
6811                                  MAC2STR(sta->addr));
6812                     ap_sta_session_timeout(hapd, sta, 0);
6813                     return;
6814           }
6815 #endif /* CONFIG_HS20 */
6816 
6817 #ifndef CONFIG_NO_RRM
6818           if (len < 24 + 5 + sizeof(*report))
6819                     return;
6820           report = (const struct rrm_measurement_report_element *)
6821                     &mgmt->u.action.u.rrm.variable[2];
6822           if (mgmt->u.action.category == WLAN_ACTION_RADIO_MEASUREMENT &&
6823               mgmt->u.action.u.rrm.action == WLAN_RRM_RADIO_MEASUREMENT_REQUEST &&
6824               report->eid == WLAN_EID_MEASURE_REQUEST &&
6825               report->len >= 3 &&
6826               report->type == MEASURE_TYPE_BEACON)
6827                     hostapd_rrm_beacon_req_tx_status(hapd, mgmt, len, ok);
6828 #endif /* CONFIG_NO_RRM */
6829 }
6830 
6831 
6832 /**
6833  * ieee802_11_mgmt_cb - Process management frame TX status callback
6834  * @hapd: hostapd BSS data structure (the BSS from which the management frame
6835  * was sent from)
6836  * @buf: management frame data (starting from IEEE 802.11 header)
6837  * @len: length of frame data in octets
6838  * @stype: management frame subtype from frame control field
6839  * @ok: Whether the frame was ACK'ed
6840  */
ieee802_11_mgmt_cb(struct hostapd_data * hapd,const u8 * buf,size_t len,u16 stype,int ok)6841 void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len,
6842                               u16 stype, int ok)
6843 {
6844           const struct ieee80211_mgmt *mgmt;
6845           mgmt = (const struct ieee80211_mgmt *) buf;
6846 
6847 #ifdef CONFIG_TESTING_OPTIONS
6848           if (hapd->ext_mgmt_frame_handling) {
6849                     size_t hex_len = 2 * len + 1;
6850                     char *hex = os_malloc(hex_len);
6851 
6852                     if (hex) {
6853                               wpa_snprintf_hex(hex, hex_len, buf, len);
6854                               wpa_msg(hapd->msg_ctx, MSG_INFO,
6855                                         "MGMT-TX-STATUS stype=%u ok=%d buf=%s",
6856                                         stype, ok, hex);
6857                               os_free(hex);
6858                     }
6859                     return;
6860           }
6861 #endif /* CONFIG_TESTING_OPTIONS */
6862 
6863           switch (stype) {
6864           case WLAN_FC_STYPE_AUTH:
6865                     wpa_printf(MSG_DEBUG, "mgmt::auth cb");
6866                     handle_auth_cb(hapd, mgmt, len, ok);
6867                     break;
6868           case WLAN_FC_STYPE_ASSOC_RESP:
6869                     wpa_printf(MSG_DEBUG, "mgmt::assoc_resp cb");
6870                     handle_assoc_cb(hapd, mgmt, len, 0, ok);
6871                     break;
6872           case WLAN_FC_STYPE_REASSOC_RESP:
6873                     wpa_printf(MSG_DEBUG, "mgmt::reassoc_resp cb");
6874                     handle_assoc_cb(hapd, mgmt, len, 1, ok);
6875                     break;
6876           case WLAN_FC_STYPE_PROBE_RESP:
6877                     wpa_printf(MSG_EXCESSIVE, "mgmt::proberesp cb ok=%d", ok);
6878                     break;
6879           case WLAN_FC_STYPE_DEAUTH:
6880                     wpa_printf(MSG_DEBUG, "mgmt::deauth cb");
6881                     handle_deauth_cb(hapd, mgmt, len, ok);
6882                     break;
6883           case WLAN_FC_STYPE_DISASSOC:
6884                     wpa_printf(MSG_DEBUG, "mgmt::disassoc cb");
6885                     handle_disassoc_cb(hapd, mgmt, len, ok);
6886                     break;
6887           case WLAN_FC_STYPE_ACTION:
6888                     wpa_printf(MSG_DEBUG, "mgmt::action cb ok=%d", ok);
6889                     handle_action_cb(hapd, mgmt, len, ok);
6890                     break;
6891           default:
6892                     wpa_printf(MSG_INFO, "unknown mgmt cb frame subtype %d", stype);
6893                     break;
6894           }
6895 }
6896 
6897 
ieee802_11_get_mib(struct hostapd_data * hapd,char * buf,size_t buflen)6898 int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
6899 {
6900           /* TODO */
6901           return 0;
6902 }
6903 
6904 
ieee802_11_get_mib_sta(struct hostapd_data * hapd,struct sta_info * sta,char * buf,size_t buflen)6905 int ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
6906                                  char *buf, size_t buflen)
6907 {
6908           /* TODO */
6909           return 0;
6910 }
6911 
6912 
hostapd_tx_status(struct hostapd_data * hapd,const u8 * addr,const u8 * buf,size_t len,int ack)6913 void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr,
6914                            const u8 *buf, size_t len, int ack)
6915 {
6916           struct sta_info *sta;
6917           struct hostapd_iface *iface = hapd->iface;
6918 
6919           sta = ap_get_sta(hapd, addr);
6920           if (sta == NULL && iface->num_bss > 1) {
6921                     size_t j;
6922                     for (j = 0; j < iface->num_bss; j++) {
6923                               hapd = iface->bss[j];
6924                               sta = ap_get_sta(hapd, addr);
6925                               if (sta)
6926                                         break;
6927                     }
6928           }
6929           if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))
6930                     return;
6931           if (sta->flags & WLAN_STA_PENDING_POLL) {
6932                     wpa_printf(MSG_DEBUG, "STA " MACSTR " %s pending "
6933                                  "activity poll", MAC2STR(sta->addr),
6934                                  ack ? "ACKed" : "did not ACK");
6935                     if (ack)
6936                               sta->flags &= ~WLAN_STA_PENDING_POLL;
6937           }
6938 
6939           ieee802_1x_tx_status(hapd, sta, buf, len, ack);
6940 }
6941 
6942 
hostapd_client_poll_ok(struct hostapd_data * hapd,const u8 * addr)6943 void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr)
6944 {
6945           struct sta_info *sta;
6946           struct hostapd_iface *iface = hapd->iface;
6947 
6948           sta = ap_get_sta(hapd, addr);
6949           if (sta == NULL && iface->num_bss > 1) {
6950                     size_t j;
6951                     for (j = 0; j < iface->num_bss; j++) {
6952                               hapd = iface->bss[j];
6953                               sta = ap_get_sta(hapd, addr);
6954                               if (sta)
6955                                         break;
6956                     }
6957           }
6958           if (sta == NULL)
6959                     return;
6960           wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POLL_OK MACSTR,
6961                     MAC2STR(sta->addr));
6962           if (!(sta->flags & WLAN_STA_PENDING_POLL))
6963                     return;
6964 
6965           wpa_printf(MSG_DEBUG, "STA " MACSTR " ACKed pending "
6966                        "activity poll", MAC2STR(sta->addr));
6967           sta->flags &= ~WLAN_STA_PENDING_POLL;
6968 }
6969 
6970 
ieee802_11_rx_from_unknown(struct hostapd_data * hapd,const u8 * src,int wds)6971 void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src,
6972                                         int wds)
6973 {
6974           struct sta_info *sta;
6975 
6976           sta = ap_get_sta(hapd, src);
6977           if (sta &&
6978               ((sta->flags & WLAN_STA_ASSOC) ||
6979                ((sta->flags & WLAN_STA_ASSOC_REQ_OK) && wds))) {
6980                     if (!hapd->conf->wds_sta)
6981                               return;
6982 
6983                     if ((sta->flags & (WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK)) ==
6984                         WLAN_STA_ASSOC_REQ_OK) {
6985                               wpa_printf(MSG_DEBUG,
6986                                            "Postpone 4-address WDS mode enabling for STA "
6987                                            MACSTR " since TX status for AssocResp is not yet known",
6988                                            MAC2STR(sta->addr));
6989                               sta->pending_wds_enable = 1;
6990                               return;
6991                     }
6992 
6993                     if (wds && !(sta->flags & WLAN_STA_WDS)) {
6994                               int ret;
6995                               char ifname_wds[IFNAMSIZ + 1];
6996 
6997                               wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for "
6998                                            "STA " MACSTR " (aid %u)",
6999                                            MAC2STR(sta->addr), sta->aid);
7000                               sta->flags |= WLAN_STA_WDS;
7001                               ret = hostapd_set_wds_sta(hapd, ifname_wds,
7002                                                               sta->addr, sta->aid, 1);
7003                               if (!ret)
7004                                         hostapd_set_wds_encryption(hapd, sta,
7005                                                                          ifname_wds);
7006                     }
7007                     return;
7008           }
7009 
7010           wpa_printf(MSG_DEBUG, "Data/PS-poll frame from not associated STA "
7011                        MACSTR, MAC2STR(src));
7012           if (is_multicast_ether_addr(src) || is_zero_ether_addr(src) ||
7013               ether_addr_equal(src, hapd->own_addr)) {
7014                     /* Broadcast bit set in SA or unexpected SA?! Ignore the frame
7015                      * silently. */
7016                     return;
7017           }
7018 
7019           if (sta && (sta->flags & WLAN_STA_ASSOC_REQ_OK)) {
7020                     wpa_printf(MSG_DEBUG, "Association Response to the STA has "
7021                                  "already been sent, but no TX status yet known - "
7022                                  "ignore Class 3 frame issue with " MACSTR,
7023                                  MAC2STR(src));
7024                     return;
7025           }
7026 
7027           if (sta && (sta->flags & WLAN_STA_AUTH))
7028                     hostapd_drv_sta_disassoc(
7029                               hapd, src,
7030                               WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
7031           else
7032                     hostapd_drv_sta_deauth(
7033                               hapd, src,
7034                               WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
7035 }
7036 
7037 
hostapd_add_tpe_info(u8 * eid,u8 tx_pwr_count,enum max_tx_pwr_interpretation tx_pwr_intrpn,u8 tx_pwr_cat,u8 tx_pwr)7038 static u8 * hostapd_add_tpe_info(u8 *eid, u8 tx_pwr_count,
7039                                          enum max_tx_pwr_interpretation tx_pwr_intrpn,
7040                                          u8 tx_pwr_cat, u8 tx_pwr)
7041 {
7042           int i;
7043 
7044           *eid++ = WLAN_EID_TRANSMIT_POWER_ENVELOPE; /* Element ID */
7045           *eid++ = 2 + tx_pwr_count; /* Length */
7046 
7047           /*
7048            * Transmit Power Information field
7049            *        bits 0-2 : Maximum Transmit Power Count
7050            *        bits 3-5 : Maximum Transmit Power Interpretation
7051            *        bits 6-7 : Maximum Transmit Power Category
7052            */
7053           *eid++ = tx_pwr_count | (tx_pwr_intrpn << 3) | (tx_pwr_cat << 6);
7054 
7055           /* Maximum Transmit Power field */
7056           for (i = 0; i <= tx_pwr_count; i++)
7057                     *eid++ = tx_pwr;
7058 
7059           return eid;
7060 }
7061 
7062 
7063 /*
7064  * TODO: Extract power limits from channel data after 6G regulatory
7065  *        support.
7066  */
7067 #define REG_PSD_MAX_TXPOWER_FOR_DEFAULT_CLIENT      (-1) /* dBm/MHz */
7068 #define REG_PSD_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT  5    /* dBm/MHz */
7069 
hostapd_eid_txpower_envelope(struct hostapd_data * hapd,u8 * eid)7070 u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid)
7071 {
7072           struct hostapd_iface *iface = hapd->iface;
7073           struct hostapd_config *iconf = iface->conf;
7074           struct hostapd_hw_modes *mode = iface->current_mode;
7075           struct hostapd_channel_data *chan;
7076           int dfs, i;
7077           u8 channel, tx_pwr_count, local_pwr_constraint;
7078           int max_tx_power;
7079           u8 tx_pwr;
7080 
7081           if (!mode)
7082                     return eid;
7083 
7084           if (ieee80211_freq_to_chan(iface->freq, &channel) == NUM_HOSTAPD_MODES)
7085                     return eid;
7086 
7087           for (i = 0; i < mode->num_channels; i++) {
7088                     if (mode->channels[i].freq == iface->freq)
7089                               break;
7090           }
7091           if (i == mode->num_channels)
7092                     return eid;
7093 
7094 #ifdef CONFIG_IEEE80211AX
7095           /* IEEE Std 802.11ax-2021, Annex E.2.7 (6 GHz band in the United
7096            * States): An AP that is an Indoor Access Point per regulatory rules
7097            * shall send at least two Transmit Power Envelope elements in Beacon
7098            * and Probe Response frames as follows:
7099            *  - Maximum Transmit Power Category subfield = Default;
7100            *        Unit interpretation = Regulatory client EIRP PSD
7101            *  - Maximum Transmit Power Category subfield = Subordinate Device;
7102            *        Unit interpretation = Regulatory client EIRP PSD
7103            */
7104           if (is_6ghz_op_class(iconf->op_class)) {
7105                     enum max_tx_pwr_interpretation tx_pwr_intrpn;
7106 
7107                     /* Same Maximum Transmit Power for all 20 MHz bands */
7108                     tx_pwr_count = 0;
7109                     tx_pwr_intrpn = REGULATORY_CLIENT_EIRP_PSD;
7110 
7111                     /* Default Transmit Power Envelope for Global Operating Class */
7112                     if (hapd->iconf->reg_def_cli_eirp_psd != -1)
7113                               tx_pwr = hapd->iconf->reg_def_cli_eirp_psd;
7114                     else
7115                               tx_pwr = REG_PSD_MAX_TXPOWER_FOR_DEFAULT_CLIENT * 2;
7116 
7117                     eid = hostapd_add_tpe_info(eid, tx_pwr_count, tx_pwr_intrpn,
7118                                                      REG_DEFAULT_CLIENT, tx_pwr);
7119 
7120                     /* Indoor Access Point must include an additional TPE for
7121                      * subordinate devices */
7122                     if (he_reg_is_indoor(iconf->he_6ghz_reg_pwr_type)) {
7123                               /* TODO: Extract PSD limits from channel data */
7124                               if (hapd->iconf->reg_sub_cli_eirp_psd != -1)
7125                                         tx_pwr = hapd->iconf->reg_sub_cli_eirp_psd;
7126                               else
7127                                         tx_pwr = REG_PSD_MAX_TXPOWER_FOR_SUBORDINATE_CLIENT * 2;
7128                               eid = hostapd_add_tpe_info(eid, tx_pwr_count,
7129                                                                tx_pwr_intrpn,
7130                                                                REG_SUBORDINATE_CLIENT,
7131                                                                tx_pwr);
7132                     }
7133 
7134                     if (iconf->reg_def_cli_eirp != -1 &&
7135                         he_reg_is_sp(iconf->he_6ghz_reg_pwr_type))
7136                               eid = hostapd_add_tpe_info(
7137                                         eid, tx_pwr_count, REGULATORY_CLIENT_EIRP,
7138                                         REG_DEFAULT_CLIENT,
7139                                         hapd->iconf->reg_def_cli_eirp);
7140 
7141                     return eid;
7142           }
7143 #endif /* CONFIG_IEEE80211AX */
7144 
7145           switch (hostapd_get_oper_chwidth(iconf)) {
7146           case CONF_OPER_CHWIDTH_USE_HT:
7147                     if (iconf->secondary_channel == 0) {
7148                               /* Max Transmit Power count = 0 (20 MHz) */
7149                               tx_pwr_count = 0;
7150                     } else {
7151                               /* Max Transmit Power count = 1 (20, 40 MHz) */
7152                               tx_pwr_count = 1;
7153                     }
7154                     break;
7155           case CONF_OPER_CHWIDTH_80MHZ:
7156                     /* Max Transmit Power count = 2 (20, 40, and 80 MHz) */
7157                     tx_pwr_count = 2;
7158                     break;
7159           case CONF_OPER_CHWIDTH_80P80MHZ:
7160           case CONF_OPER_CHWIDTH_160MHZ:
7161                     /* Max Transmit Power count = 3 (20, 40, 80, 160/80+80 MHz) */
7162                     tx_pwr_count = 3;
7163                     break;
7164           default:
7165                     return eid;
7166           }
7167 
7168           /*
7169            * Below local_pwr_constraint logic is referred from
7170            * hostapd_eid_pwr_constraint.
7171            *
7172            * Check if DFS is required by regulatory.
7173            */
7174           dfs = hostapd_is_dfs_required(hapd->iface);
7175           if (dfs < 0)
7176                     dfs = 0;
7177 
7178           /*
7179            * In order to meet regulations when TPC is not implemented using
7180            * a transmit power that is below the legal maximum (including any
7181            * mitigation factor) should help. In this case, indicate 3 dB below
7182            * maximum allowed transmit power.
7183            */
7184           if (hapd->iconf->local_pwr_constraint == -1)
7185                     local_pwr_constraint = (dfs == 0) ? 0 : 3;
7186           else
7187                     local_pwr_constraint = hapd->iconf->local_pwr_constraint;
7188 
7189           /*
7190            * A STA that is not an AP shall use a transmit power less than or
7191            * equal to the local maximum transmit power level for the channel.
7192            * The local maximum transmit power can be calculated from the formula:
7193            * local max TX pwr = max TX pwr - local pwr constraint
7194            * Where max TX pwr is maximum transmit power level specified for
7195            * channel in Country element and local pwr constraint is specified
7196            * for channel in this Power Constraint element.
7197            */
7198           chan = &mode->channels[i];
7199           max_tx_power = chan->max_tx_power - local_pwr_constraint;
7200 
7201           /*
7202            * Local Maximum Transmit power is encoded as two's complement
7203            * with a 0.5 dB step.
7204            */
7205           max_tx_power *= 2; /* in 0.5 dB steps */
7206           if (max_tx_power > 127) {
7207                     /* 63.5 has special meaning of 63.5 dBm or higher */
7208                     max_tx_power = 127;
7209           }
7210           if (max_tx_power < -128)
7211                     max_tx_power = -128;
7212           if (max_tx_power < 0)
7213                     tx_pwr = 0x80 + max_tx_power + 128;
7214           else
7215                     tx_pwr = max_tx_power;
7216 
7217           return hostapd_add_tpe_info(eid, tx_pwr_count, LOCAL_EIRP,
7218                                             0 /* Reserved for bands other than 6 GHz */,
7219                                             tx_pwr);
7220 }
7221 
7222 
hostapd_eid_wb_chsw_wrapper(struct hostapd_data * hapd,u8 * eid)7223 u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid)
7224 {
7225           u8 bw, chan1 = 0, chan2 = 0;
7226           int freq1;
7227 
7228           if (!hapd->cs_freq_params.channel ||
7229               (!hapd->cs_freq_params.vht_enabled &&
7230                !hapd->cs_freq_params.he_enabled &&
7231                !hapd->cs_freq_params.eht_enabled))
7232                     return eid;
7233 
7234           /* bandwidth: 0: 40, 1: 80, 160, 80+80, 4: 320 as per
7235            * IEEE P802.11-REVme/D4.0, 9.4.2.159 and Table 9-314. */
7236           switch (hapd->cs_freq_params.bandwidth) {
7237           case 40:
7238                     bw = 0;
7239                     break;
7240           case 80:
7241                     bw = 1;
7242                     break;
7243           case 160:
7244                     bw = 1;
7245                     break;
7246           case 320:
7247                     bw = 4;
7248                     break;
7249           default:
7250                     /* not valid VHT bandwidth or not in CSA */
7251                     return eid;
7252           }
7253 
7254           freq1 = hapd->cs_freq_params.center_freq1 ?
7255                     hapd->cs_freq_params.center_freq1 :
7256                     hapd->cs_freq_params.freq;
7257           if (ieee80211_freq_to_chan(freq1, &chan1) !=
7258               HOSTAPD_MODE_IEEE80211A)
7259                     return eid;
7260 
7261           if (hapd->cs_freq_params.center_freq2 &&
7262               ieee80211_freq_to_chan(hapd->cs_freq_params.center_freq2,
7263                                            &chan2) != HOSTAPD_MODE_IEEE80211A)
7264                     return eid;
7265 
7266           *eid++ = WLAN_EID_CHANNEL_SWITCH_WRAPPER;
7267           *eid++ = 5; /* Length of Channel Switch Wrapper */
7268           *eid++ = WLAN_EID_WIDE_BW_CHSWITCH;
7269           *eid++ = 3; /* Length of Wide Bandwidth Channel Switch element */
7270           *eid++ = bw; /* New Channel Width */
7271           if (hapd->cs_freq_params.bandwidth == 160) {
7272                     /* Update the CCFS0 and CCFS1 values in the element based on
7273                      * IEEE P802.11-REVme/D4.0, Table 9-314 */
7274 
7275                     /* CCFS1 - The channel center frequency index of the 160 MHz
7276                      * channel. */
7277                     chan2 = chan1;
7278 
7279                     /* CCFS0 - The channel center frequency index of the 80 MHz
7280                      * channel segment that contains the primary channel. */
7281                     if (hapd->cs_freq_params.channel < chan1)
7282                               chan1 -= 8;
7283                     else
7284                               chan1 += 8;
7285           }
7286           *eid++ = chan1; /* New Channel Center Frequency Segment 0 */
7287           *eid++ = chan2; /* New Channel Center Frequency Segment 1 */
7288 
7289           return eid;
7290 }
7291 
7292 
hostapd_eid_nr_db_len(struct hostapd_data * hapd,size_t * current_len)7293 static size_t hostapd_eid_nr_db_len(struct hostapd_data *hapd,
7294                                             size_t *current_len)
7295 {
7296           struct hostapd_neighbor_entry *nr;
7297           size_t total_len = 0, len = *current_len;
7298 
7299           dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
7300                                list) {
7301                     if (!nr->nr || wpabuf_len(nr->nr) < 12)
7302                               continue;
7303 
7304                     if (nr->short_ssid == hapd->conf->ssid.short_ssid)
7305                               continue;
7306 
7307                     /* Start a new element */
7308                     if (!len ||
7309                         len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
7310                               len = RNR_HEADER_LEN;
7311                               total_len += RNR_HEADER_LEN;
7312                     }
7313 
7314                     len += RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN;
7315                     total_len += RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN;
7316           }
7317 
7318           *current_len = len;
7319           return total_len;
7320 }
7321 
7322 
7323 struct mbssid_ie_profiles {
7324           u8 start;
7325           u8 end;
7326 };
7327 
hostapd_skip_rnr(size_t i,struct mbssid_ie_profiles * skip_profiles,bool ap_mld,u8 tbtt_info_len,bool mld_update,struct hostapd_data * reporting_hapd,struct hostapd_data * bss)7328 static bool hostapd_skip_rnr(size_t i, struct mbssid_ie_profiles *skip_profiles,
7329                                    bool ap_mld, u8 tbtt_info_len, bool mld_update,
7330                                    struct hostapd_data *reporting_hapd,
7331                                    struct hostapd_data *bss)
7332 {
7333           if (skip_profiles &&
7334               i >= skip_profiles->start && i < skip_profiles->end)
7335                     return true;
7336 
7337           /* No need to report if length is for normal TBTT and the BSS is
7338            * affiliated with an AP MLD. MLD TBTT will include this. */
7339           if (tbtt_info_len == RNR_TBTT_INFO_LEN && ap_mld)
7340                     return true;
7341 
7342           /* No need to report if length is for MLD TBTT and the BSS is not
7343            * affiliated with an aP MLD. Normal TBTT will include this. */
7344           if (tbtt_info_len == RNR_TBTT_INFO_MLD_LEN && !ap_mld)
7345                     return true;
7346 
7347 #ifdef CONFIG_IEEE80211BE
7348           /* If building for co-location and they are ML partners, no need to
7349            * include since the ML RNR will carry this. */
7350           if (!mld_update && hostapd_is_ml_partner(reporting_hapd, bss))
7351                     return true;
7352 
7353           /* If building for ML RNR and they are not ML partners, don't include.
7354            */
7355           if (mld_update && !hostapd_is_ml_partner(reporting_hapd, bss))
7356                     return true;
7357 #endif /* CONFIG_IEEE80211BE */
7358 
7359           return false;
7360 }
7361 
7362 
7363 static size_t
hostapd_eid_rnr_iface_len(struct hostapd_data * hapd,struct hostapd_data * reporting_hapd,size_t * current_len,struct mbssid_ie_profiles * skip_profiles,bool mld_update)7364 hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
7365                                 struct hostapd_data *reporting_hapd,
7366                                 size_t *current_len,
7367                                 struct mbssid_ie_profiles *skip_profiles,
7368                                 bool mld_update)
7369 {
7370           size_t total_len = 0, len = *current_len;
7371           int tbtt_count, total_tbtt_count = 0;
7372           size_t i, start;
7373           u8 tbtt_info_len = mld_update ? RNR_TBTT_INFO_MLD_LEN :
7374                     RNR_TBTT_INFO_LEN;
7375 
7376 repeat_rnr_len:
7377           start = 0;
7378           tbtt_count = 0;
7379 
7380           while (start < hapd->iface->num_bss) {
7381                     if (!len ||
7382                         len + RNR_TBTT_HEADER_LEN + tbtt_info_len > 255 ||
7383                         tbtt_count >= RNR_TBTT_INFO_COUNT_MAX) {
7384                               len = RNR_HEADER_LEN;
7385                               total_len += RNR_HEADER_LEN;
7386                               tbtt_count = 0;
7387                     }
7388 
7389                     len += RNR_TBTT_HEADER_LEN;
7390                     total_len += RNR_TBTT_HEADER_LEN;
7391 
7392                     for (i = start; i < hapd->iface->num_bss; i++) {
7393                               struct hostapd_data *bss = hapd->iface->bss[i];
7394                               bool ap_mld = false;
7395 
7396                               if (!bss || !bss->conf || !bss->started)
7397                                         continue;
7398 
7399 #ifdef CONFIG_IEEE80211BE
7400                               ap_mld = bss->conf->mld_ap;
7401 #endif /* CONFIG_IEEE80211BE */
7402 
7403                               if (bss == reporting_hapd ||
7404                                   bss->conf->ignore_broadcast_ssid)
7405                                         continue;
7406 
7407                               if (hostapd_skip_rnr(i, skip_profiles, ap_mld,
7408                                                        tbtt_info_len, mld_update,
7409                                                        reporting_hapd, bss))
7410                                         continue;
7411 
7412                               if (len + tbtt_info_len > 255 ||
7413                                   tbtt_count >= RNR_TBTT_INFO_COUNT_MAX)
7414                                         break;
7415 
7416                               len += tbtt_info_len;
7417                               total_len += tbtt_info_len;
7418                               tbtt_count++;
7419                     }
7420                     start = i;
7421           }
7422 
7423           total_tbtt_count += tbtt_count;
7424 
7425           /* If building for co-location, re-build again but this time include
7426            * ML TBTTs.
7427            */
7428           if (!mld_update && tbtt_info_len == RNR_TBTT_INFO_LEN) {
7429                     tbtt_info_len = RNR_TBTT_INFO_MLD_LEN;
7430 
7431                     /* If no TBTT was found, adjust the len and total_len since it
7432                      * would have incremented before we checked all BSSs. */
7433                     if (!tbtt_count) {
7434                               len -= RNR_TBTT_HEADER_LEN;
7435                               total_len -= RNR_TBTT_HEADER_LEN;
7436                     }
7437 
7438                     goto repeat_rnr_len;
7439           }
7440 
7441           /* This is possible when in the re-built case and no suitable TBTT was
7442            * found. Adjust the length accordingly. */
7443           if (!tbtt_count && total_tbtt_count) {
7444                     len -= RNR_TBTT_HEADER_LEN;
7445                     total_len -= RNR_TBTT_HEADER_LEN;
7446           }
7447 
7448           if (!total_tbtt_count)
7449                     total_len = 0;
7450           else
7451                     *current_len = len;
7452 
7453           return total_len;
7454 }
7455 
7456 
7457 enum colocation_mode {
7458           NO_COLOCATED_6GHZ,
7459           STANDALONE_6GHZ,
7460           COLOCATED_6GHZ,
7461           COLOCATED_LOWER_BAND,
7462 };
7463 
get_colocation_mode(struct hostapd_data * hapd)7464 static enum colocation_mode get_colocation_mode(struct hostapd_data *hapd)
7465 {
7466           u8 i;
7467           bool is_6ghz = is_6ghz_op_class(hapd->iconf->op_class);
7468 
7469           if (!hapd->iface || !hapd->iface->interfaces)
7470                     return NO_COLOCATED_6GHZ;
7471 
7472           if (is_6ghz && hapd->iface->interfaces->count == 1)
7473                     return STANDALONE_6GHZ;
7474 
7475           for (i = 0; i < hapd->iface->interfaces->count; i++) {
7476                     struct hostapd_iface *iface;
7477                     bool is_colocated_6ghz;
7478 
7479                     iface = hapd->iface->interfaces->iface[i];
7480                     if (iface == hapd->iface || !iface || !iface->conf)
7481                               continue;
7482 
7483                     is_colocated_6ghz = is_6ghz_op_class(iface->conf->op_class);
7484                     if (!is_6ghz && is_colocated_6ghz)
7485                               return COLOCATED_LOWER_BAND;
7486                     if (is_6ghz && !is_colocated_6ghz)
7487                               return COLOCATED_6GHZ;
7488           }
7489 
7490           if (is_6ghz)
7491                     return STANDALONE_6GHZ;
7492 
7493           return NO_COLOCATED_6GHZ;
7494 }
7495 
7496 
hostapd_eid_rnr_colocation_len(struct hostapd_data * hapd,size_t * current_len)7497 static size_t hostapd_eid_rnr_colocation_len(struct hostapd_data *hapd,
7498                                                        size_t *current_len)
7499 {
7500           struct hostapd_iface *iface;
7501           size_t len = 0;
7502           size_t i;
7503 
7504           if (!hapd->iface || !hapd->iface->interfaces)
7505                     return 0;
7506 
7507           for (i = 0; i < hapd->iface->interfaces->count; i++) {
7508                     iface = hapd->iface->interfaces->iface[i];
7509 
7510                     if (!iface || iface == hapd->iface ||
7511                         iface->state != HAPD_IFACE_ENABLED ||
7512                         !is_6ghz_op_class(iface->conf->op_class))
7513                               continue;
7514 
7515                     len += hostapd_eid_rnr_iface_len(iface->bss[0], hapd,
7516                                                              current_len, NULL, false);
7517           }
7518 
7519           return len;
7520 }
7521 
7522 
hostapd_eid_rnr_mlo_len(struct hostapd_data * hapd,u32 type,size_t * current_len)7523 static size_t hostapd_eid_rnr_mlo_len(struct hostapd_data *hapd, u32 type,
7524                                               size_t *current_len)
7525 {
7526           size_t len = 0;
7527 #ifdef CONFIG_IEEE80211BE
7528           struct hostapd_iface *iface;
7529           size_t i;
7530 
7531           if (!hapd->iface || !hapd->iface->interfaces || !hapd->conf->mld_ap)
7532                     return 0;
7533 
7534           /* TODO: Allow for FILS/Action as well */
7535           if (type != WLAN_FC_STYPE_BEACON && type != WLAN_FC_STYPE_PROBE_RESP)
7536                     return 0;
7537 
7538           for (i = 0; i < hapd->iface->interfaces->count; i++) {
7539                     iface = hapd->iface->interfaces->iface[i];
7540 
7541                     if (!iface || iface == hapd->iface ||
7542                         hapd->iface->freq == iface->freq)
7543                               continue;
7544 
7545                     len += hostapd_eid_rnr_iface_len(iface->bss[0], hapd,
7546                                                              current_len, NULL, true);
7547           }
7548 #endif /* CONFIG_IEEE80211BE */
7549 
7550           return len;
7551 }
7552 
7553 
hostapd_eid_rnr_len(struct hostapd_data * hapd,u32 type,bool include_mld_params)7554 size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type,
7555                                  bool include_mld_params)
7556 {
7557           size_t total_len = 0, current_len = 0;
7558           enum colocation_mode mode = get_colocation_mode(hapd);
7559 
7560           switch (type) {
7561           case WLAN_FC_STYPE_BEACON:
7562                     if (hapd->conf->rnr)
7563                               total_len += hostapd_eid_nr_db_len(hapd, &current_len);
7564                     /* fallthrough */
7565           case WLAN_FC_STYPE_PROBE_RESP:
7566                     if (mode == COLOCATED_LOWER_BAND)
7567                               total_len +=
7568                                         hostapd_eid_rnr_colocation_len(hapd,
7569                                                                              &current_len);
7570 
7571                     if (hapd->conf->rnr && hapd->iface->num_bss > 1 &&
7572                         !hapd->iconf->mbssid)
7573                               total_len += hostapd_eid_rnr_iface_len(hapd, hapd,
7574                                                                              &current_len,
7575                                                                              NULL, false);
7576                     break;
7577           case WLAN_FC_STYPE_ACTION:
7578                     if (hapd->iface->num_bss > 1 && mode == STANDALONE_6GHZ)
7579                               total_len += hostapd_eid_rnr_iface_len(hapd, hapd,
7580                                                                              &current_len,
7581                                                                              NULL, false);
7582                     break;
7583           }
7584 
7585           /* For EMA Beacons, MLD neighbor repoting is added as part of
7586            * MBSSID RNR. */
7587           if (include_mld_params &&
7588               (type != WLAN_FC_STYPE_BEACON ||
7589                hapd->iconf->mbssid != ENHANCED_MBSSID_ENABLED))
7590                     total_len += hostapd_eid_rnr_mlo_len(hapd, type, &current_len);
7591 
7592           return total_len;
7593 }
7594 
7595 
hostapd_eid_nr_db(struct hostapd_data * hapd,u8 * eid,size_t * current_len)7596 static u8 * hostapd_eid_nr_db(struct hostapd_data *hapd, u8 *eid,
7597                                     size_t *current_len)
7598 {
7599           struct hostapd_neighbor_entry *nr;
7600           size_t len = *current_len;
7601           u8 *size_offset = (eid - len) + 1;
7602 
7603           dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
7604                                list) {
7605                     if (!nr->nr || wpabuf_len(nr->nr) < 12)
7606                               continue;
7607 
7608                     if (nr->short_ssid == hapd->conf->ssid.short_ssid)
7609                               continue;
7610 
7611                     /* Start a new element */
7612                     if (!len ||
7613                         len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
7614                               *eid++ = WLAN_EID_REDUCED_NEIGHBOR_REPORT;
7615                               size_offset = eid++;
7616                               len = RNR_HEADER_LEN;
7617                     }
7618 
7619                     /* TBTT Information Header subfield (2 octets) */
7620                     *eid++ = 0;
7621                     /* TBTT Information Length */
7622                     *eid++ = RNR_TBTT_INFO_LEN;
7623                     /* Operating Class */
7624                     *eid++ = wpabuf_head_u8(nr->nr)[10];
7625                     /* Channel Number */
7626                     *eid++ = wpabuf_head_u8(nr->nr)[11];
7627                     len += RNR_TBTT_HEADER_LEN;
7628                     /* TBTT Information Set */
7629                     /* TBTT Information field */
7630                     /* Neighbor AP TBTT Offset */
7631                     *eid++ = RNR_NEIGHBOR_AP_OFFSET_UNKNOWN;
7632                     /* BSSID */
7633                     os_memcpy(eid, nr->bssid, ETH_ALEN);
7634                     eid += ETH_ALEN;
7635                     /* Short SSID */
7636                     os_memcpy(eid, &nr->short_ssid, 4);
7637                     eid += 4;
7638                     /* BSS parameters */
7639                     *eid++ = nr->bss_parameters;
7640                     /* 20 MHz PSD */
7641                     *eid++ = RNR_20_MHZ_PSD_MAX_TXPOWER;
7642                     len += RNR_TBTT_INFO_LEN;
7643                     *size_offset = (eid - size_offset) - 1;
7644           }
7645 
7646           *current_len = len;
7647           return eid;
7648 }
7649 
7650 
hostapd_eid_rnr_bss(struct hostapd_data * hapd,struct hostapd_data * reporting_hapd,struct mbssid_ie_profiles * skip_profiles,size_t i,u8 * tbtt_count,size_t * len,u8 ** pos,u8 ** tbtt_count_pos,u8 tbtt_info_len,u8 op_class,bool mld_update)7651 static bool hostapd_eid_rnr_bss(struct hostapd_data *hapd,
7652                                         struct hostapd_data *reporting_hapd,
7653                                         struct mbssid_ie_profiles *skip_profiles,
7654                                         size_t i, u8 *tbtt_count, size_t *len,
7655                                         u8 **pos, u8 **tbtt_count_pos, u8 tbtt_info_len,
7656                                         u8 op_class, bool mld_update)
7657 {
7658           struct hostapd_iface *iface = hapd->iface;
7659           struct hostapd_data *bss = iface->bss[i];
7660           u8 bss_param = 0;
7661           bool ap_mld = false;
7662           u8 *eid = *pos;
7663 
7664 #ifdef CONFIG_IEEE80211BE
7665           ap_mld = !!hapd->conf->mld_ap;
7666 #endif /* CONFIG_IEEE80211BE */
7667 
7668           if (!bss || !bss->conf || !bss->started ||
7669               bss == reporting_hapd || bss->conf->ignore_broadcast_ssid)
7670                     return false;
7671 
7672           if (hostapd_skip_rnr(i, skip_profiles, ap_mld, tbtt_info_len,
7673                                    mld_update, reporting_hapd, bss))
7674               return false;
7675 
7676           if (*len + RNR_TBTT_INFO_LEN > 255 ||
7677               *tbtt_count >= RNR_TBTT_INFO_COUNT_MAX)
7678                     return true;
7679 
7680           if (!(*tbtt_count)) {
7681                     /* Add neighbor report header info only if there is at least
7682                      * one TBTT info available. */
7683                     *tbtt_count_pos = eid++;
7684                     *eid++ = tbtt_info_len;
7685                     *eid++ = op_class;
7686                     *eid++ = bss->iconf->channel;
7687                     *len += RNR_TBTT_HEADER_LEN;
7688           }
7689 
7690           *eid++ = RNR_NEIGHBOR_AP_OFFSET_UNKNOWN;
7691           os_memcpy(eid, bss->own_addr, ETH_ALEN);
7692           eid += ETH_ALEN;
7693           os_memcpy(eid, &bss->conf->ssid.short_ssid, 4);
7694           eid += 4;
7695           if (bss->conf->ssid.short_ssid == reporting_hapd->conf->ssid.short_ssid)
7696                     bss_param |= RNR_BSS_PARAM_SAME_SSID;
7697 
7698           if (iface->conf->mbssid != MBSSID_DISABLED && iface->num_bss > 1) {
7699                     bss_param |= RNR_BSS_PARAM_MULTIPLE_BSSID;
7700                     if (bss == hostapd_mbssid_get_tx_bss(hapd))
7701                               bss_param |= RNR_BSS_PARAM_TRANSMITTED_BSSID;
7702           }
7703 
7704           if (is_6ghz_op_class(hapd->iconf->op_class) &&
7705               bss->conf->unsol_bcast_probe_resp_interval)
7706                     bss_param |= RNR_BSS_PARAM_UNSOLIC_PROBE_RESP_ACTIVE;
7707 
7708           bss_param |= RNR_BSS_PARAM_CO_LOCATED;
7709 
7710           *eid++ = bss_param;
7711           *eid++ = RNR_20_MHZ_PSD_MAX_TXPOWER;
7712 
7713 #ifdef CONFIG_IEEE80211BE
7714           if (ap_mld) {
7715                     u8 param_ch = bss->eht_mld_bss_param_change;
7716                     bool is_partner;
7717 
7718                     /* If BSS is not a partner of the reporting_hapd
7719                      *  a) MLD ID advertised shall be 255.
7720                      *  b) Link ID advertised shall be 15.
7721                      *  c) BPCC advertised shall be 255 */
7722                     is_partner = hostapd_is_ml_partner(bss, reporting_hapd);
7723                     /* MLD ID */
7724                     *eid++ = is_partner ? hostapd_get_mld_id(bss) : 0xFF;
7725                     /* Link ID (Bit 3 to Bit 0)
7726                      * BPCC (Bit 4 to Bit 7) */
7727                     *eid++ = is_partner ?
7728                               bss->mld_link_id | ((param_ch & 0xF) << 4) :
7729                               (MAX_NUM_MLD_LINKS | 0xF0);
7730                     /* BPCC (Bit 3 to Bit 0) */
7731                     *eid = is_partner ? ((param_ch & 0xF0) >> 4) : 0x0F;
7732 #ifdef CONFIG_TESTING_OPTIONS
7733                     if (bss->conf->mld_indicate_disabled)
7734                               *eid |= RNR_TBTT_INFO_MLD_PARAM2_LINK_DISABLED;
7735 #endif /* CONFIG_TESTING_OPTIONS */
7736                     eid++;
7737           }
7738 #endif /* CONFIG_IEEE80211BE */
7739 
7740           *len += tbtt_info_len;
7741           (*tbtt_count)++;
7742           *pos = eid;
7743 
7744           return false;
7745 }
7746 
7747 
hostapd_eid_rnr_iface(struct hostapd_data * hapd,struct hostapd_data * reporting_hapd,u8 * eid,size_t * current_len,struct mbssid_ie_profiles * skip_profiles,bool mld_update)7748 static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
7749                                           struct hostapd_data *reporting_hapd,
7750                                           u8 *eid, size_t *current_len,
7751                                           struct mbssid_ie_profiles *skip_profiles,
7752                                           bool mld_update)
7753 {
7754           struct hostapd_iface *iface = hapd->iface;
7755           size_t i, start;
7756           size_t len = *current_len;
7757           u8 *eid_start = eid, *size_offset = (eid - len) + 1;
7758           u8 *tbtt_count_pos = size_offset + 1;
7759           u8 tbtt_count, total_tbtt_count = 0, op_class, channel;
7760           u8 tbtt_info_len = mld_update ? RNR_TBTT_INFO_MLD_LEN :
7761                     RNR_TBTT_INFO_LEN;
7762 
7763           if (!(iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA) || !iface->freq)
7764                     return eid;
7765 
7766           if (ieee80211_freq_to_channel_ext(iface->freq,
7767                                                     hapd->iconf->secondary_channel,
7768                                                     hostapd_get_oper_chwidth(hapd->iconf),
7769                                                     &op_class, &channel) ==
7770               NUM_HOSTAPD_MODES)
7771                     return eid;
7772 
7773 repeat_rnr:
7774           start = 0;
7775           tbtt_count = 0;
7776           while (start < iface->num_bss) {
7777                     if (!len ||
7778                         len + RNR_TBTT_HEADER_LEN + tbtt_info_len > 255 ||
7779                         tbtt_count >= RNR_TBTT_INFO_COUNT_MAX) {
7780                               eid_start = eid;
7781                               *eid++ = WLAN_EID_REDUCED_NEIGHBOR_REPORT;
7782                               size_offset = eid++;
7783                               len = RNR_HEADER_LEN;
7784                               tbtt_count = 0;
7785                     }
7786 
7787                     for (i = start; i < iface->num_bss; i++) {
7788                               if (hostapd_eid_rnr_bss(hapd, reporting_hapd,
7789                                                             skip_profiles, i,
7790                                                             &tbtt_count, &len, &eid,
7791                                                             &tbtt_count_pos, tbtt_info_len,
7792                                                             op_class, mld_update))
7793                                         break;
7794                     }
7795 
7796                     start = i;
7797 
7798                     if (tbtt_count) {
7799                               *tbtt_count_pos = RNR_TBTT_INFO_COUNT(tbtt_count - 1);
7800                               *size_offset = (eid - size_offset) - 1;
7801                     }
7802           }
7803 
7804           total_tbtt_count += tbtt_count;
7805 
7806           /* If building for co-location, re-build again but this time include
7807            * ML TBTTs.
7808            */
7809           if (!mld_update && tbtt_info_len == RNR_TBTT_INFO_LEN) {
7810                     tbtt_info_len = RNR_TBTT_INFO_MLD_LEN;
7811                     goto repeat_rnr;
7812           }
7813 
7814           if (!total_tbtt_count)
7815                     return eid_start;
7816 
7817           *current_len = len;
7818           return eid;
7819 }
7820 
7821 
hostapd_eid_rnr_colocation(struct hostapd_data * hapd,u8 * eid,size_t * current_len)7822 u8 * hostapd_eid_rnr_colocation(struct hostapd_data *hapd, u8 *eid,
7823                                         size_t *current_len)
7824 {
7825           struct hostapd_iface *iface;
7826           size_t i;
7827 
7828           if (!hapd->iface || !hapd->iface->interfaces)
7829                     return eid;
7830 
7831           for (i = 0; i < hapd->iface->interfaces->count; i++) {
7832                     iface = hapd->iface->interfaces->iface[i];
7833 
7834                     if (!iface || iface == hapd->iface ||
7835                         iface->state != HAPD_IFACE_ENABLED ||
7836                         !is_6ghz_op_class(iface->conf->op_class))
7837                               continue;
7838 
7839                     eid = hostapd_eid_rnr_iface(iface->bss[0], hapd, eid,
7840                                                       current_len, NULL, false);
7841           }
7842 
7843           return eid;
7844 }
7845 
7846 
hostapd_eid_rnr_mlo(struct hostapd_data * hapd,u32 type,u8 * eid,size_t * current_len)7847 u8 * hostapd_eid_rnr_mlo(struct hostapd_data *hapd, u32 type,
7848                                u8 *eid, size_t *current_len)
7849 {
7850 #ifdef CONFIG_IEEE80211BE
7851           struct hostapd_iface *iface;
7852           size_t i;
7853 
7854           if (!hapd->iface || !hapd->iface->interfaces || !hapd->conf->mld_ap)
7855                     return eid;
7856 
7857           /* TODO: Allow for FILS/Action as well */
7858           if (type != WLAN_FC_STYPE_BEACON && type != WLAN_FC_STYPE_PROBE_RESP)
7859                     return eid;
7860 
7861           for (i = 0; i < hapd->iface->interfaces->count; i++) {
7862                     iface = hapd->iface->interfaces->iface[i];
7863 
7864                     if (!iface || iface == hapd->iface ||
7865                         hapd->iface->freq == iface->freq)
7866                               continue;
7867 
7868                     eid = hostapd_eid_rnr_iface(iface->bss[0], hapd, eid,
7869                                                       current_len, NULL, true);
7870           }
7871 #endif /* CONFIG_IEEE80211BE */
7872 
7873           return eid;
7874 }
7875 
7876 
hostapd_eid_rnr(struct hostapd_data * hapd,u8 * eid,u32 type,bool include_mld_params)7877 u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type,
7878                          bool include_mld_params)
7879 {
7880           u8 *eid_start = eid;
7881           size_t current_len = 0;
7882           enum colocation_mode mode = get_colocation_mode(hapd);
7883 
7884           switch (type) {
7885           case WLAN_FC_STYPE_BEACON:
7886                     if (hapd->conf->rnr)
7887                               eid = hostapd_eid_nr_db(hapd, eid, &current_len);
7888                     /* fallthrough */
7889           case WLAN_FC_STYPE_PROBE_RESP:
7890                     if (mode == COLOCATED_LOWER_BAND)
7891                               eid = hostapd_eid_rnr_colocation(hapd, eid,
7892                                                                        &current_len);
7893 
7894                     if (hapd->conf->rnr && hapd->iface->num_bss > 1 &&
7895                         !hapd->iconf->mbssid)
7896                               eid = hostapd_eid_rnr_iface(hapd, hapd, eid,
7897                                                                 &current_len, NULL, false);
7898                     break;
7899           case WLAN_FC_STYPE_ACTION:
7900                     if (hapd->iface->num_bss > 1 && mode == STANDALONE_6GHZ)
7901                               eid = hostapd_eid_rnr_iface(hapd, hapd, eid,
7902                                                                 &current_len, NULL, false);
7903                     break;
7904           default:
7905                     return eid_start;
7906           }
7907 
7908           /* For EMA Beacons, MLD neighbor repoting is added as part of
7909            * MBSSID RNR. */
7910           if (include_mld_params &&
7911               (type != WLAN_FC_STYPE_BEACON ||
7912                hapd->iconf->mbssid != ENHANCED_MBSSID_ENABLED))
7913                     eid = hostapd_eid_rnr_mlo(hapd, type, eid, &current_len);
7914 
7915           if (eid == eid_start + 2)
7916                     return eid_start;
7917 
7918           return eid;
7919 }
7920 
7921 
mbssid_known_bss(unsigned int i,const u8 * known_bss,size_t known_bss_len)7922 static bool mbssid_known_bss(unsigned int i, const u8 *known_bss,
7923                                    size_t known_bss_len)
7924 {
7925           if (!known_bss || known_bss_len <= i / 8)
7926                     return false;
7927           known_bss = &known_bss[i / 8];
7928           return *known_bss & (u8) (BIT(i % 8));
7929 }
7930 
7931 
hostapd_mbssid_ext_capa(struct hostapd_data * bss,struct hostapd_data * tx_bss,u8 * buf)7932 static size_t hostapd_mbssid_ext_capa(struct hostapd_data *bss,
7933                                               struct hostapd_data *tx_bss, u8 *buf)
7934 {
7935           u8 ext_capa_tx[20], *ext_capa_tx_end, ext_capa[20], *ext_capa_end;
7936           size_t ext_capa_len, ext_capa_tx_len;
7937 
7938           ext_capa_tx_end = hostapd_eid_ext_capab(tx_bss, ext_capa_tx,
7939                                                             true);
7940           ext_capa_tx_len = ext_capa_tx_end - ext_capa_tx;
7941           ext_capa_end = hostapd_eid_ext_capab(bss, ext_capa, true);
7942           ext_capa_len = ext_capa_end - ext_capa;
7943           if (ext_capa_tx_len != ext_capa_len ||
7944               os_memcmp(ext_capa_tx, ext_capa, ext_capa_len) != 0) {
7945                     os_memcpy(buf, ext_capa, ext_capa_len);
7946                     return ext_capa_len;
7947           }
7948 
7949           return 0;
7950 }
7951 
7952 
hostapd_eid_mbssid_elem_len(struct hostapd_data * hapd,u32 frame_type,size_t * bss_index,const u8 * known_bss,size_t known_bss_len)7953 static size_t hostapd_eid_mbssid_elem_len(struct hostapd_data *hapd,
7954                                                     u32 frame_type, size_t *bss_index,
7955                                                     const u8 *known_bss,
7956                                                     size_t known_bss_len)
7957 {
7958           struct hostapd_data *tx_bss = hostapd_mbssid_get_tx_bss(hapd);
7959           size_t len, i;
7960           u8 ext_capa[20];
7961 
7962           /* Element ID: 1 octet
7963            * Length: 1 octet
7964            * MaxBSSID Indicator: 1 octet
7965            * Optional Subelements: vatiable
7966            *
7967            * Total fixed length: 3 octets
7968            *
7969            * 1 octet in len for the MaxBSSID Indicator field.
7970            */
7971           len = 1;
7972 
7973           for (i = *bss_index; i < hapd->iface->num_bss; i++) {
7974                     struct hostapd_data *bss = hapd->iface->bss[i];
7975                     const u8 *auth, *rsn = NULL, *rsnx = NULL;
7976                     size_t nontx_profile_len, auth_len;
7977                     u8 ie_count = 0;
7978 
7979                     if (!bss || !bss->conf || !bss->started ||
7980                         mbssid_known_bss(i, known_bss, known_bss_len))
7981                               continue;
7982 
7983                     /*
7984                      * Sublement ID: 1 octet
7985                      * Length: 1 octet
7986                      * Nontransmitted capabilities: 4 octets
7987                      * SSID element: 2 + variable
7988                      * Multiple BSSID Index Element: 3 octets (+2 octets in beacons)
7989                      * Fixed length = 1 + 1 + 4 + 2 + 3 = 11
7990                      */
7991                     nontx_profile_len = 11 + bss->conf->ssid.ssid_len;
7992 
7993                     if (frame_type == WLAN_FC_STYPE_BEACON)
7994                               nontx_profile_len += 2;
7995 
7996                     auth = wpa_auth_get_wpa_ie(bss->wpa_auth, &auth_len);
7997                     if (auth) {
7998                               rsn = get_ie(auth, auth_len, WLAN_EID_RSN);
7999                               if (rsn)
8000                                         nontx_profile_len += 2 + rsn[1];
8001 
8002                               rsnx = get_ie(auth, auth_len, WLAN_EID_RSNX);
8003                               if (rsnx)
8004                                         nontx_profile_len += 2 + rsnx[1];
8005                     }
8006 
8007                     nontx_profile_len += hostapd_mbssid_ext_capa(bss, tx_bss,
8008                                                                            ext_capa);
8009 
8010                     if (!rsn && hostapd_wpa_ie(tx_bss, WLAN_EID_RSN))
8011                               ie_count++;
8012                     if (!rsnx && hostapd_wpa_ie(tx_bss, WLAN_EID_RSNX))
8013                               ie_count++;
8014                     if (bss->conf->xrates_supported)
8015                               nontx_profile_len += 8;
8016                     else if (hapd->conf->xrates_supported)
8017                               ie_count++;
8018                     if (ie_count)
8019                               nontx_profile_len += 4 + ie_count;
8020 
8021                     if (len + nontx_profile_len > 255)
8022                               break;
8023 
8024                     len += nontx_profile_len;
8025           }
8026 
8027           *bss_index = i;
8028 
8029           /* Add 2 octets to get the full size of the element */
8030           return len + 2;
8031 }
8032 
8033 
hostapd_eid_mbssid_len(struct hostapd_data * hapd,u32 frame_type,u8 * elem_count,const u8 * known_bss,size_t known_bss_len,size_t * rnr_len)8034 size_t hostapd_eid_mbssid_len(struct hostapd_data *hapd, u32 frame_type,
8035                                     u8 *elem_count, const u8 *known_bss,
8036                                     size_t known_bss_len, size_t *rnr_len)
8037 {
8038           size_t len = 0, bss_index = 1;
8039           bool ap_mld = false;
8040 
8041 #ifdef CONFIG_IEEE80211BE
8042           ap_mld = hapd->conf->mld_ap;
8043 #endif /* CONFIG_IEEE80211BE */
8044 
8045           if (!hapd->iconf->mbssid || hapd->iface->num_bss <= 1 ||
8046               (frame_type != WLAN_FC_STYPE_BEACON &&
8047                frame_type != WLAN_FC_STYPE_PROBE_RESP))
8048                     return 0;
8049 
8050           if (frame_type == WLAN_FC_STYPE_BEACON) {
8051                     if (!elem_count) {
8052                               wpa_printf(MSG_INFO,
8053                                            "MBSSID: Insufficient data for Beacon frames");
8054                               return 0;
8055                     }
8056                     *elem_count = 0;
8057           }
8058 
8059           while (bss_index < hapd->iface->num_bss) {
8060                     size_t rnr_count = bss_index;
8061 
8062                     len += hostapd_eid_mbssid_elem_len(hapd, frame_type,
8063                                                                &bss_index, known_bss,
8064                                                                known_bss_len);
8065 
8066                     if (frame_type == WLAN_FC_STYPE_BEACON)
8067                               *elem_count += 1;
8068                     if (hapd->iconf->mbssid == ENHANCED_MBSSID_ENABLED && rnr_len) {
8069                               size_t rnr_cur_len = 0;
8070                               struct mbssid_ie_profiles skip_profiles = {
8071                                         rnr_count, bss_index
8072                               };
8073 
8074                               *rnr_len += hostapd_eid_rnr_iface_len(
8075                                         hapd, hostapd_mbssid_get_tx_bss(hapd),
8076                                         &rnr_cur_len, &skip_profiles, ap_mld);
8077                     }
8078           }
8079 
8080           if (hapd->iconf->mbssid == ENHANCED_MBSSID_ENABLED && rnr_len)
8081                     *rnr_len += hostapd_eid_rnr_len(hapd, frame_type, false);
8082 
8083           return len;
8084 }
8085 
8086 
hostapd_eid_mbssid_elem(struct hostapd_data * hapd,u8 * eid,u8 * end,u32 frame_type,u8 max_bssid_indicator,size_t * bss_index,u8 elem_count,const u8 * known_bss,size_t known_bss_len)8087 static u8 * hostapd_eid_mbssid_elem(struct hostapd_data *hapd, u8 *eid, u8 *end,
8088                                             u32 frame_type, u8 max_bssid_indicator,
8089                                             size_t *bss_index, u8 elem_count,
8090                                             const u8 *known_bss, size_t known_bss_len)
8091 {
8092           struct hostapd_data *tx_bss = hostapd_mbssid_get_tx_bss(hapd);
8093           size_t i;
8094           u8 *eid_len_offset, *max_bssid_indicator_offset;
8095 
8096           *eid++ = WLAN_EID_MULTIPLE_BSSID;
8097           eid_len_offset = eid++;
8098           max_bssid_indicator_offset = eid++;
8099 
8100           for (i = *bss_index; i < hapd->iface->num_bss; i++) {
8101                     struct hostapd_data *bss = hapd->iface->bss[i];
8102                     struct hostapd_bss_config *conf;
8103                     u8 *eid_len_pos, *nontx_bss_start = eid;
8104                     const u8 *auth, *rsn = NULL, *rsnx = NULL;
8105                     u8 ie_count = 0, non_inherit_ie[3];
8106                     size_t auth_len = 0;
8107                     u16 capab_info;
8108 
8109                     if (!bss || !bss->conf || !bss->started ||
8110                         mbssid_known_bss(i, known_bss, known_bss_len))
8111                               continue;
8112                     conf = bss->conf;
8113 
8114                     *eid++ = WLAN_MBSSID_SUBELEMENT_NONTRANSMITTED_BSSID_PROFILE;
8115                     eid_len_pos = eid++;
8116 
8117                     capab_info = hostapd_own_capab_info(bss);
8118                     *eid++ = WLAN_EID_NONTRANSMITTED_BSSID_CAPA;
8119                     *eid++ = sizeof(capab_info);
8120                     WPA_PUT_LE16(eid, capab_info);
8121                     eid += sizeof(capab_info);
8122 
8123                     *eid++ = WLAN_EID_SSID;
8124                     *eid++ = conf->ssid.ssid_len;
8125                     os_memcpy(eid, conf->ssid.ssid, conf->ssid.ssid_len);
8126                     eid += conf->ssid.ssid_len;
8127 
8128                     *eid++ = WLAN_EID_MULTIPLE_BSSID_INDEX;
8129                     if (frame_type == WLAN_FC_STYPE_BEACON) {
8130                               *eid++ = 3;
8131                               *eid++ = i; /* BSSID Index */
8132                               if (hapd->iconf->mbssid == ENHANCED_MBSSID_ENABLED &&
8133                                   (conf->dtim_period % elem_count))
8134                                         conf->dtim_period = elem_count;
8135                               *eid++ = conf->dtim_period;
8136                               /* The driver is expected to update the DTIM Count
8137                                * field for each BSS that corresponds to a
8138                                * nontransmitted BSSID. The value is initialized to
8139                                * 0 here so that the DTIM count would be somewhat
8140                                * functional even if the driver were not to update
8141                                * this. */
8142                               *eid++ = 0; /* DTIM Count */
8143                     } else {
8144                               /* Probe Request frame does not include DTIM Period and
8145                                * DTIM Count fields. */
8146                               *eid++ = 1;
8147                               *eid++ = i; /* BSSID Index */
8148                     }
8149 
8150                     auth = wpa_auth_get_wpa_ie(bss->wpa_auth, &auth_len);
8151                     if (auth) {
8152                               rsn = get_ie(auth, auth_len, WLAN_EID_RSN);
8153                               if (rsn) {
8154                                         os_memcpy(eid, rsn, 2 + rsn[1]);
8155                                         eid += 2 + rsn[1];
8156                               }
8157 
8158                               rsnx = get_ie(auth, auth_len, WLAN_EID_RSNX);
8159                               if (rsnx) {
8160                                         os_memcpy(eid, rsnx, 2 + rsnx[1]);
8161                                         eid += 2 + rsnx[1];
8162                               }
8163                     }
8164 
8165                     eid += hostapd_mbssid_ext_capa(bss, tx_bss, eid);
8166 
8167                     /* List of Element ID values in increasing order */
8168                     if (!rsn && hostapd_wpa_ie(tx_bss, WLAN_EID_RSN))
8169                               non_inherit_ie[ie_count++] = WLAN_EID_RSN;
8170                     if (hapd->conf->xrates_supported &&
8171                         !bss->conf->xrates_supported)
8172                               non_inherit_ie[ie_count++] = WLAN_EID_EXT_SUPP_RATES;
8173                     if (!rsnx && hostapd_wpa_ie(tx_bss, WLAN_EID_RSNX))
8174                               non_inherit_ie[ie_count++] = WLAN_EID_RSNX;
8175                     if (ie_count) {
8176                               *eid++ = WLAN_EID_EXTENSION;
8177                               *eid++ = 2 + ie_count + 1;
8178                               *eid++ = WLAN_EID_EXT_NON_INHERITANCE;
8179                               *eid++ = ie_count;
8180                               os_memcpy(eid, non_inherit_ie, ie_count);
8181                               eid += ie_count;
8182                               *eid++ = 0; /* No Element ID Extension List */
8183                     }
8184 
8185                     *eid_len_pos = (eid - eid_len_pos) - 1;
8186 
8187                     if (((eid - eid_len_offset) - 1) > 255) {
8188                               eid = nontx_bss_start;
8189                               break;
8190                     }
8191           }
8192 
8193           *bss_index = i;
8194           *max_bssid_indicator_offset = max_bssid_indicator;
8195           if (*max_bssid_indicator_offset < 1)
8196                     *max_bssid_indicator_offset = 1;
8197           *eid_len_offset = (eid - eid_len_offset) - 1;
8198           return eid;
8199 }
8200 
8201 
hostapd_eid_mbssid(struct hostapd_data * hapd,u8 * eid,u8 * end,unsigned int frame_stype,u8 elem_count,u8 ** elem_offset,const u8 * known_bss,size_t known_bss_len,u8 * rnr_eid,u8 * rnr_count,u8 ** rnr_offset,size_t rnr_len)8202 u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end,
8203                               unsigned int frame_stype, u8 elem_count,
8204                               u8 **elem_offset,
8205                               const u8 *known_bss, size_t known_bss_len, u8 *rnr_eid,
8206                               u8 *rnr_count, u8 **rnr_offset, size_t rnr_len)
8207 {
8208           size_t bss_index = 1, cur_len = 0;
8209           u8 elem_index = 0, *rnr_start_eid = rnr_eid;
8210           bool add_rnr, ap_mld = false;
8211 
8212 #ifdef CONFIG_IEEE80211BE
8213           ap_mld = hapd->conf->mld_ap;
8214 #endif /* CONFIG_IEEE80211BE */
8215 
8216           if (!hapd->iconf->mbssid || hapd->iface->num_bss <= 1 ||
8217               (frame_stype != WLAN_FC_STYPE_BEACON &&
8218                frame_stype != WLAN_FC_STYPE_PROBE_RESP))
8219                     return eid;
8220 
8221           if (frame_stype == WLAN_FC_STYPE_BEACON && !elem_offset) {
8222                     wpa_printf(MSG_INFO,
8223                                  "MBSSID: Insufficient data for Beacon frames");
8224                     return eid;
8225           }
8226 
8227           add_rnr = hapd->iconf->mbssid == ENHANCED_MBSSID_ENABLED &&
8228                     frame_stype == WLAN_FC_STYPE_BEACON &&
8229                     rnr_eid && rnr_count && rnr_offset && rnr_len;
8230 
8231           while (bss_index < hapd->iface->num_bss) {
8232                     unsigned int rnr_start_count = bss_index;
8233 
8234                     if (frame_stype == WLAN_FC_STYPE_BEACON) {
8235                               if (elem_index == elem_count) {
8236                                         wpa_printf(MSG_WARNING,
8237                                                      "MBSSID: Larger number of elements than there is room in the provided array");
8238                                         break;
8239                               }
8240 
8241                               elem_offset[elem_index] = eid;
8242                               elem_index = elem_index + 1;
8243                     }
8244                     eid = hostapd_eid_mbssid_elem(hapd, eid, end, frame_stype,
8245                                                         hostapd_max_bssid_indicator(hapd),
8246                                                         &bss_index, elem_count,
8247                                                         known_bss, known_bss_len);
8248 
8249                     if (add_rnr) {
8250                               struct mbssid_ie_profiles skip_profiles = {
8251                                         rnr_start_count, bss_index
8252                               };
8253 
8254                               rnr_offset[*rnr_count] = rnr_eid;
8255                               *rnr_count = *rnr_count + 1;
8256                               cur_len = 0;
8257                               rnr_eid = hostapd_eid_rnr_iface(
8258                                         hapd, hostapd_mbssid_get_tx_bss(hapd),
8259                                         rnr_eid, &cur_len, &skip_profiles, ap_mld);
8260                     }
8261           }
8262 
8263           if (add_rnr && (size_t) (rnr_eid - rnr_start_eid) < rnr_len) {
8264                     rnr_offset[*rnr_count] = rnr_eid;
8265                     *rnr_count = *rnr_count + 1;
8266                     cur_len = 0;
8267 
8268                     if (hapd->conf->rnr)
8269                               rnr_eid = hostapd_eid_nr_db(hapd, rnr_eid, &cur_len);
8270                     if (get_colocation_mode(hapd) == COLOCATED_LOWER_BAND)
8271                               rnr_eid = hostapd_eid_rnr_colocation(hapd, rnr_eid,
8272                                                                            &cur_len);
8273           }
8274 
8275           return eid;
8276 }
8277 
8278 #endif /* CONFIG_NATIVE_WINDOWS */
8279