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