1 /*
2  * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "utils/includes.h"
8 
9 #include "utils/common.h"
10 #include "utils/eloop.h"
11 #include "crypto/sha1.h"
12 #include "common/ieee802_11_defs.h"
13 #include "common/eapol_common.h"
14 #include "ap/wpa_auth.h"
15 #include "ap/ap_config.h"
16 #include "utils/wpa_debug.h"
17 #include "ap/hostapd.h"
18 #include "ap/wpa_auth_i.h"
19 #include "esp_wifi_driver.h"
20 #include "esp_wifi_types.h"
21 #include "esp_wpa3_i.h"
22 #include "esp_wps.h"
23 #include "esp_wps_i.h"
24 
25 #include "ap/sta_info.h"
26 #include "common/sae.h"
27 #include "ap/ieee802_11.h"
28 #define WIFI_PASSWORD_LEN_MAX 65
29 
30 struct hostapd_data *global_hapd;
31 
32 #ifdef CONFIG_SAE
33 extern struct k_sem * g_wpa3_hostap_auth_api_lock;
34 #endif /* CONFIG_SAE */
35 
hostapd_get_hapd_data(void)36 struct hostapd_data *hostapd_get_hapd_data(void)
37 {
38     return global_hapd;
39 }
40 
hostap_init(void)41 void *hostap_init(void)
42 {
43     struct wifi_ssid *ssid = esp_wifi_ap_get_prof_ap_ssid_internal();
44     struct hostapd_data *hapd = NULL;
45     struct wpa_auth_config *auth_conf;
46     u16 spp_attrubute = 0;
47     u8 pairwise_cipher;
48     wifi_pmf_config_t pmf_cfg = {0};
49     uint8_t authmode;
50 
51     hapd = (struct hostapd_data *)os_zalloc(sizeof(struct hostapd_data));
52 
53     if (hapd == NULL) {
54         return NULL;
55     }
56 
57     hapd->conf = (struct hostapd_bss_config *)os_zalloc(sizeof(struct hostapd_bss_config));
58 
59     if (hapd->conf == NULL) {
60         os_free(hapd);
61         return NULL;
62     }
63 
64     auth_conf = (struct wpa_auth_config *)os_zalloc(sizeof(struct  wpa_auth_config));
65 
66     if (auth_conf == NULL) {
67         goto fail;
68     }
69 
70     hapd->conf->sae_pwe = esp_wifi_get_config_sae_pwe_h2e_internal(WIFI_IF_AP);
71     auth_conf->sae_pwe = hapd->conf->sae_pwe;
72 
73     authmode = esp_wifi_ap_get_prof_authmode_internal();
74     if (authmode == WIFI_AUTH_WPA_PSK) {
75         auth_conf->wpa = WPA_PROTO_WPA;
76     }
77     if (authmode == WIFI_AUTH_WPA2_PSK) {
78         auth_conf->wpa = WPA_PROTO_RSN;
79     }
80     if (authmode == WIFI_AUTH_WPA_WPA2_PSK) {
81         auth_conf->wpa = WPA_PROTO_RSN | WPA_PROTO_WPA;
82     }
83     if (authmode == WIFI_AUTH_WPA3_PSK || authmode == WIFI_AUTH_WPA2_WPA3_PSK) {
84         auth_conf->wpa = WPA_PROTO_RSN;
85     }
86 
87     pairwise_cipher = esp_wifi_ap_get_prof_pairwise_cipher_internal();
88 
89 #ifdef CONFIG_IEEE80211W
90     if((auth_conf->wpa & WPA_PROTO_RSN) == WPA_PROTO_RSN)
91     {
92         esp_wifi_get_pmf_config_internal(&pmf_cfg, WIFI_IF_AP);
93         if (pmf_cfg.required) {
94             pairwise_cipher = WIFI_CIPHER_TYPE_CCMP;
95         }
96     }
97 #endif /* CONFIG_IEEE80211W */
98 
99     /* TKIP is compulsory in WPA Mode */
100     if (auth_conf->wpa == WPA_PROTO_WPA && pairwise_cipher == WIFI_CIPHER_TYPE_CCMP) {
101         pairwise_cipher = WIFI_CIPHER_TYPE_TKIP_CCMP;
102     }
103     if (pairwise_cipher == WIFI_CIPHER_TYPE_TKIP) {
104         auth_conf->wpa_group = WPA_CIPHER_TKIP;
105         auth_conf->wpa_pairwise = WPA_CIPHER_TKIP;
106         auth_conf->rsn_pairwise = WPA_CIPHER_TKIP;
107     } else if (pairwise_cipher == WIFI_CIPHER_TYPE_CCMP) {
108         auth_conf->wpa_group = WPA_CIPHER_CCMP;
109         auth_conf->wpa_pairwise = WPA_CIPHER_CCMP;
110         auth_conf->rsn_pairwise = WPA_CIPHER_CCMP;
111     } else {
112         auth_conf->wpa_group = WPA_CIPHER_TKIP;
113         auth_conf->wpa_pairwise = WPA_CIPHER_CCMP | WPA_CIPHER_TKIP;
114         auth_conf->rsn_pairwise = WPA_CIPHER_CCMP | WPA_CIPHER_TKIP;
115     }
116 
117     auth_conf->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
118     auth_conf->eapol_version = EAPOL_VERSION;
119 
120     hapd->conf->sae_anti_clogging_threshold = SAE_ANTI_CLOGGING_THRESHOLD;
121 #ifdef CONFIG_IEEE80211W
122     if (pmf_cfg.required && pmf_cfg.capable) {
123         auth_conf->ieee80211w = MGMT_FRAME_PROTECTION_REQUIRED;
124         auth_conf->wpa_key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
125         wpa_printf(MSG_DEBUG, "%s :pmf required", __func__);
126     } else if (pmf_cfg.capable && !pmf_cfg.required) {
127         auth_conf->ieee80211w = MGMT_FRAME_PROTECTION_OPTIONAL;
128         auth_conf->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
129         wpa_printf(MSG_DEBUG, "%s : pmf optional", __func__);
130     }
131 
132     if (authmode == WIFI_AUTH_WPA2_WPA3_PSK) {
133         auth_conf->wpa_key_mgmt |= WPA_KEY_MGMT_SAE;
134     }
135 
136     if (authmode == WIFI_AUTH_WPA3_PSK) {
137         auth_conf->wpa_key_mgmt = WPA_KEY_MGMT_SAE;
138     }
139 #endif /* CONFIG_IEEE80211W */
140 
141     spp_attrubute = esp_wifi_get_spp_attrubute_internal(WIFI_IF_AP);
142     auth_conf->spp_sup.capable = ((spp_attrubute & WPA_CAPABILITY_SPP_CAPABLE) ? SPP_AMSDU_CAP_ENABLE : SPP_AMSDU_CAP_DISABLE);
143     auth_conf->spp_sup.require = ((spp_attrubute & WPA_CAPABILITY_SPP_REQUIRED) ? SPP_AMSDU_REQ_ENABLE : SPP_AMSDU_REQ_DISABLE);
144 
145     memcpy(hapd->conf->ssid.ssid, ssid->ssid, ssid->len);
146     hapd->conf->ssid.ssid_len = ssid->len;
147     hapd->conf->wpa_key_mgmt = auth_conf->wpa_key_mgmt;
148     hapd->conf->ssid.wpa_passphrase = (char *)os_zalloc(WIFI_PASSWORD_LEN_MAX);
149     if (hapd->conf->ssid.wpa_passphrase == NULL) {
150         goto fail;
151     }
152 
153 #ifdef CONFIG_SAE
154     if (authmode == WIFI_AUTH_WPA3_PSK ||
155         authmode == WIFI_AUTH_WPA2_WPA3_PSK) {
156         if (wpa3_hostap_auth_init(hapd) != 0) {
157             goto fail;
158         }
159     }
160 #endif /* CONFIG_SAE */
161 
162     os_memcpy(hapd->conf->ssid.wpa_passphrase, esp_wifi_ap_get_prof_password_internal(), strlen((char *)esp_wifi_ap_get_prof_password_internal()));
163     hapd->conf->ssid.wpa_passphrase[WIFI_PASSWORD_LEN_MAX - 1] = '\0';
164     hapd->conf->max_num_sta = esp_wifi_ap_get_max_sta_conn();
165 
166     hapd->conf->ap_max_inactivity = 5 * 60;
167     hostapd_setup_wpa_psk(hapd->conf);
168 
169     esp_wifi_get_macaddr_internal(WIFI_IF_AP, hapd->own_addr);
170 
171     hapd->wpa_auth = wpa_init(hapd->own_addr, auth_conf, NULL);
172     if (hapd->wpa_auth == NULL) {
173         goto fail;
174     }
175 
176     esp_wifi_set_appie_internal(WIFI_APPIE_WPA, hapd->wpa_auth->wpa_ie, (uint16_t)hapd->wpa_auth->wpa_ie_len, 0);
177     os_free(auth_conf);
178     global_hapd = hapd;
179 
180     return (void *)hapd;
181 fail:
182     if (hapd->conf->ssid.wpa_passphrase != NULL) {
183         os_free(hapd->conf->ssid.wpa_passphrase);
184     }
185     if (auth_conf != NULL) {
186         os_free(auth_conf);
187     }
188     os_free(hapd->conf);
189     os_free(hapd);
190     hapd = NULL;
191     return NULL;
192 }
193 
hostapd_cleanup(struct hostapd_data * hapd)194 void hostapd_cleanup(struct hostapd_data *hapd)
195 {
196     if (hapd == NULL) {
197         return;
198     }
199     if(hapd->wpa_auth) {
200         wpa_deinit(hapd->wpa_auth);
201         hapd->wpa_auth = NULL;
202     }
203 
204     if (hapd->conf) {
205         forced_memzero(hapd->conf->ssid.wpa_passphrase, WIFI_PASSWORD_LEN_MAX);
206         os_free(hapd->conf->ssid.wpa_passphrase);
207         hostapd_config_free_bss(hapd->conf);
208         hapd->conf = NULL;
209     }
210 
211 #ifdef CONFIG_SAE
212 
213     struct hostapd_sae_commit_queue *q, *tmp;
214 
215     if (dl_list_empty(&hapd->sae_commit_queue)) {
216         dl_list_for_each_safe(q, tmp, &hapd->sae_commit_queue,
217                 struct hostapd_sae_commit_queue, list) {
218             dl_list_del(&q->list);
219             os_free(q);
220         }
221     }
222 
223 #endif /* CONFIG_SAE */
224 #ifdef CONFIG_WPS_REGISTRAR
225     if (esp_wifi_get_wps_type_internal () != WPS_TYPE_DISABLE ||
226         esp_wifi_get_wps_status_internal() != WPS_STATUS_DISABLE) {
227         esp_wifi_ap_wps_disable();
228     }
229 #endif /* CONFIG_WPS_REGISTRAR */
230     os_free(hapd);
231     global_hapd = NULL;
232 
233 }
234 
235 
hostap_deinit(void * data)236 bool hostap_deinit(void *data)
237 {
238     struct hostapd_data *hapd = (struct hostapd_data *)data;
239 
240     if (hapd == NULL) {
241         return true;
242     }
243     esp_wifi_unset_appie_internal(WIFI_APPIE_WPA);
244     esp_wifi_unset_appie_internal(WIFI_APPIE_ASSOC_RESP);
245 
246 #ifdef CONFIG_WPS_REGISTRAR
247     wifi_ap_wps_disable_internal();
248 #endif
249 #ifdef CONFIG_SAE
250     wpa3_hostap_auth_deinit();
251     /* Wait till lock is released by wpa3 task */
252     if (g_wpa3_hostap_auth_api_lock &&
253         WPA3_HOSTAP_AUTH_API_LOCK() == pdTRUE) {
254         WPA3_HOSTAP_AUTH_API_UNLOCK();
255     }
256 #endif /* CONFIG_SAE */
257 
258     hostapd_cleanup(hapd);
259 
260     return true;
261 }
262 
esp_wifi_build_rsnxe(struct hostapd_data * hapd,u8 * eid,size_t len)263 int esp_wifi_build_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len)
264 {
265     u8 *pos = eid;
266     u16 capab = 0;
267     size_t flen;
268 
269     if (!(hapd->wpa_auth->conf.wpa & WPA_PROTO_RSN)) {
270         return 0;
271     }
272 
273     if (wpa_key_mgmt_sae(hapd->wpa_auth->conf.wpa_key_mgmt) &&
274         (hapd->conf->sae_pwe == SAE_PWE_HASH_TO_ELEMENT
275          || hapd->conf->sae_pwe == SAE_PWE_BOTH)) {
276         capab |= BIT(WLAN_RSNX_CAPAB_SAE_H2E);
277     }
278 
279     flen = 1;
280     if (len < 2 + flen || !capab) {
281         return 0; /* no supported extended RSN capabilities */
282     }
283     capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */
284 
285     *pos++ = WLAN_EID_RSNX;
286     *pos++ = flen;
287     *pos++ = capab & 0x00ff;
288 
289     return pos - eid;
290 }
291 
esp_send_assoc_resp(struct hostapd_data * hapd,const u8 * addr,u16 status_code,bool omit_rsnxe,int subtype)292 u16 esp_send_assoc_resp(struct hostapd_data *hapd, const u8 *addr,
293         u16 status_code, bool omit_rsnxe, int subtype)
294 {
295 #define ASSOC_RESP_LENGTH 20
296     u8 buf[ASSOC_RESP_LENGTH];
297     wifi_mgmt_frm_req_t *reply = NULL;
298     int send_len = 0;
299 
300     int res = WLAN_STATUS_SUCCESS;
301 
302     if (!omit_rsnxe) {
303         send_len = esp_wifi_build_rsnxe(hapd, buf, ASSOC_RESP_LENGTH);
304     }
305 
306     esp_wifi_set_appie_internal(WIFI_APPIE_ASSOC_RESP, buf, send_len, 0);
307 
308     reply = os_zalloc(sizeof(wifi_mgmt_frm_req_t) + sizeof(uint16_t));
309     if (!reply) {
310         wpa_printf(MSG_ERROR, "failed to allocate memory for assoc response");
311         res = WLAN_STATUS_UNSPECIFIED_FAILURE;
312         goto done;
313     }
314     reply->ifx = WIFI_IF_AP;
315     reply->subtype = subtype;
316     os_memcpy(reply->da, addr, ETH_ALEN);
317     reply->data_len = sizeof(uint16_t);
318 
319     ((uint16_t *)reply->data)[0] = status_code;
320     if (esp_wifi_send_mgmt_frm_internal(reply) != 0) {
321         res = WLAN_STATUS_UNSPECIFIED_FAILURE;
322         wpa_printf(MSG_INFO, "esp_send_assoc_resp_failed: send failed");
323     }
324 #undef ASSOC_RESP_LENGTH
325 done:
326     os_free(reply);
327     return res;
328 }
329 
wpa_status_to_reason_code(int status)330 uint8_t wpa_status_to_reason_code(int status)
331 {
332     switch (status) {
333     case WLAN_STATUS_INVALID_IE:
334         return WLAN_REASON_INVALID_IE;
335     case WLAN_STATUS_GROUP_CIPHER_NOT_VALID:
336         return WLAN_REASON_GROUP_CIPHER_NOT_VALID;
337     case WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID:
338         return WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID;
339     case WLAN_STATUS_AKMP_NOT_VALID:
340         return WLAN_REASON_AKMP_NOT_VALID;
341     case WLAN_STATUS_CIPHER_REJECTED_PER_POLICY:
342         return WLAN_REASON_CIPHER_SUITE_REJECTED;
343     case WLAN_STATUS_INVALID_PMKID:
344         return WLAN_REASON_INVALID_PMKID;
345     case WLAN_STATUS_INVALID_MDIE:
346         return WLAN_REASON_INVALID_MDE;
347     default:
348         return WLAN_REASON_UNSPECIFIED;
349     }
350 }
351 
hostap_new_assoc_sta(struct sta_info * sta,uint8_t * bssid,uint8_t * wpa_ie,uint8_t wpa_ie_len,uint8_t * rsnxe,uint8_t rsnxe_len,bool * pmf_enable,int subtype,uint8_t * pairwise_cipher,uint8_t * reason)352 bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie,
353                           uint8_t wpa_ie_len, uint8_t *rsnxe, uint8_t rsnxe_len,
354                           bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *reason)
355 {
356     struct hostapd_data *hapd = (struct hostapd_data*)esp_wifi_get_hostap_private_internal();
357     enum wpa_validate_result res = WPA_IE_OK;
358     int status = WLAN_STATUS_SUCCESS;
359     bool omit_rsnxe = false;
360 
361     if (!sta || !bssid || !wpa_ie) {
362         return false;
363     }
364 
365     if (hapd) {
366         if (hapd->wpa_auth->conf.wpa) {
367             if (sta->wpa_sm) {
368                 wpa_auth_sta_deinit(sta->wpa_sm);
369             }
370 
371             sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, bssid);
372             wpa_printf(MSG_DEBUG, "init wpa sm=%p", sta->wpa_sm);
373 
374             if (sta->wpa_sm == NULL) {
375                 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
376                 goto send_resp;
377             }
378 
379             res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, wpa_ie, wpa_ie_len, rsnxe, rsnxe_len);
380 
381 #ifdef CONFIG_SAE
382             if (wpa_auth_uses_sae(sta->wpa_sm) && sta->sae &&
383                     sta->sae->state == SAE_ACCEPTED) {
384                 wpa_auth_add_sae_pmkid(sta->wpa_sm, sta->sae->pmkid);
385             }
386 #endif /* CONFIG_SAE */
387 
388             status = wpa_res_to_status_code(res);
389 
390 send_resp:
391             if (!rsnxe) {
392                 omit_rsnxe = true;
393             }
394 
395             if (esp_send_assoc_resp(hapd, bssid, status, omit_rsnxe, subtype) != WLAN_STATUS_SUCCESS) {
396                 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
397             }
398 
399             if (status != WLAN_STATUS_SUCCESS) {
400                 *reason = wpa_status_to_reason_code(status);
401                 return false;
402             }
403 
404             //Check whether AP uses Management Frame Protection for this connection
405             *pmf_enable = wpa_auth_uses_mfp(sta->wpa_sm);
406             *pairwise_cipher = GET_BIT_POSITION(sta->wpa_sm->pairwise);
407         }
408 
409         wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm);
410     }
411 
412     return true;
413 }
414 
415 #ifdef CONFIG_WPS_REGISTRAR
ap_free_sta_timeout(void * ctx,void * data)416 static void ap_free_sta_timeout(void *ctx, void *data)
417 {
418     struct hostapd_data *hapd = (struct hostapd_data *) ctx;
419     u8 *addr = (u8 *) data;
420     struct sta_info *sta = ap_get_sta(hapd, addr);
421 
422     if (sta) {
423         ap_free_sta(hapd, sta);
424     }
425 
426     os_free(addr);
427 }
428 #endif
429 
wpa_ap_remove(u8 * bssid)430 bool wpa_ap_remove(u8* bssid)
431 {
432     struct hostapd_data *hapd = hostapd_get_hapd_data();
433 
434     if (!hapd) {
435         return false;
436     }
437     struct sta_info *sta = ap_get_sta(hapd, bssid);
438     if (!sta) {
439         return false;
440     }
441 
442 #ifdef CONFIG_SAE
443     if (sta->lock) {
444         if (os_semphr_take(sta->lock, 0)) {
445             ap_free_sta(hapd, sta);
446         } else {
447             sta->remove_pending = true;
448         }
449         return true;
450     }
451 #endif /* CONFIG_SAE */
452 
453 #ifdef CONFIG_WPS_REGISTRAR
454     wpa_printf(MSG_DEBUG, "wps_status=%d", wps_get_status());
455     if (wps_get_status() == WPS_STATUS_PENDING) {
456         u8 *addr = os_malloc(ETH_ALEN);
457 
458         if (!addr) {
459             return false;
460         }
461         os_memcpy(addr, sta->addr, ETH_ALEN);
462         eloop_register_timeout(0, 10000, ap_free_sta_timeout, hapd, addr);
463     } else
464 #endif
465         ap_free_sta(hapd, sta);
466 
467     return true;
468 }
469