1 /*
2  * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <string.h>
8 
9 #include "utils/includes.h"
10 #include "rsn_supp/wpa.h"
11 #include "utils/common.h"
12 #include "common/eapol_common.h"
13 #include "utils/wpa_debug.h"
14 #include "common/ieee802_11_defs.h"
15 #include "crypto/dh_group5.h"
16 #include "wps/wps_i.h"
17 #include "wps/wps_dev_attr.h"
18 #include "eap_peer/eap_defs.h"
19 #include "eap_peer/eap_common.h"
20 #include "esp_wifi_driver.h"
21 #include "esp_event.h"
22 #include "esp_wifi.h"
23 #include "esp_err.h"
24 #include "esp_private/wifi.h"
25 
26 #define API_MUTEX_TAKE() do {\
27     if (!s_wps_api_lock) {\
28         s_wps_api_lock = xSemaphoreCreateRecursiveMutex();\
29         if (!s_wps_api_lock) {\
30             wpa_printf(MSG_ERROR, "wps api lock create failed");\
31             return ESP_ERR_NO_MEM;\
32         }\
33     }\
34     xSemaphoreTakeRecursive(s_wps_api_lock, portMAX_DELAY);\
35 } while(0)
36 
37 #define API_MUTEX_GIVE() xSemaphoreGiveRecursive(s_wps_api_lock)
38 #define DATA_MUTEX_TAKE() xSemaphoreTakeRecursive(s_wps_data_lock, portMAX_DELAY)
39 #define DATA_MUTEX_GIVE() xSemaphoreGiveRecursive(s_wps_data_lock)
40 
41 #define WPS_ADDR_LEN 6
42 #ifdef USE_WPS_TASK
43 struct wps_rx_param {
44     u8 sa[WPS_ADDR_LEN];
45     u8 *buf;
46     int len;
47     STAILQ_ENTRY(wps_rx_param) bqentry;
48 };
49 static STAILQ_HEAD(,wps_rx_param) s_wps_rxq;
50 
51 typedef struct {
52     void *arg;
53     int ret; /* return value */
54 } wps_ioctl_param_t;
55 
56 static TaskHandle_t s_wps_task_hdl = NULL;
57 static void *s_wps_queue = NULL;
58 static void *s_wps_api_lock = NULL;  /* Used in WPS public API only, never be freed */
59 static void *s_wps_api_sem = NULL;   /* Sync semaphore used between WPS publi API caller task and WPS task */
60 static void *s_wps_data_lock = NULL;
61 static void *s_wps_task_create_sem = NULL;
62 static bool s_wps_enabled = false;
63 static uint8_t s_wps_sig_cnt[SIG_WPS_NUM] = {0};
64 
65 #endif
66 
67 void wifi_wps_scan_done(void *arg, STATUS status);
68 void wifi_wps_scan(void);
69 int wifi_station_wps_start(void);
70 int wps_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len);
71 void wifi_wps_start_internal(void);
72 int wifi_wps_enable_internal(const esp_wps_config_t *config);
73 int wifi_wps_disable_internal(void);
74 void wifi_station_wps_timeout_internal(void);
75 void wifi_station_wps_msg_timeout_internal(void);
76 void wifi_station_wps_success_internal(void);
77 void wifi_wps_scan_internal(void);
78 void wifi_station_wps_eapol_start_handle_internal(void);
79 void wps_add_discard_ap(u8 *bssid);
80 
81 struct wps_sm *gWpsSm = NULL;
82 static wps_factory_information_t *s_factory_info = NULL;
83 
84 #ifdef CONFIG_WPS_TESTING
85 int wps_version_number = 0x20;
86 int wps_testing_dummy_cred = 0;
87 #endif /* CONFIG_WPS_TESTING */
88 
wps_get_type(void)89 int wps_get_type(void)
90 {
91     return esp_wifi_get_wps_type_internal();
92 }
93 
wps_set_type(uint32_t type)94 int wps_set_type(uint32_t type)
95 {
96     return esp_wifi_set_wps_type_internal(type);
97 }
98 
wps_get_status(void)99 int wps_get_status(void)
100 {
101     return esp_wifi_get_wps_status_internal();
102 }
103 
wps_set_status(uint32_t status)104 int wps_set_status(uint32_t status)
105 {
106     return esp_wifi_set_wps_status_internal(status);
107 }
108 
wps_rxq_init(void)109 static void wps_rxq_init(void)
110 {
111     DATA_MUTEX_TAKE();
112     STAILQ_INIT(&s_wps_rxq);
113     DATA_MUTEX_GIVE();
114 }
115 
wps_rxq_enqueue(struct wps_rx_param * param)116 static void wps_rxq_enqueue(struct wps_rx_param *param)
117 {
118     DATA_MUTEX_TAKE();
119     STAILQ_INSERT_TAIL(&s_wps_rxq,param, bqentry);
120     DATA_MUTEX_GIVE();
121 }
122 
wps_rxq_dequeue(void)123 static struct wps_rx_param * wps_rxq_dequeue(void)
124 {
125     struct wps_rx_param *param = NULL;
126     DATA_MUTEX_TAKE();
127     if ((param = STAILQ_FIRST(&s_wps_rxq)) != NULL) {
128         STAILQ_REMOVE_HEAD(&s_wps_rxq, bqentry);
129         STAILQ_NEXT(param,bqentry) = NULL;
130     }
131     DATA_MUTEX_GIVE();
132     return param;
133 }
134 
wps_rxq_deinit(void)135 static void wps_rxq_deinit(void)
136 {
137     struct wps_rx_param *param = NULL;
138     DATA_MUTEX_TAKE();
139     while ((param = STAILQ_FIRST(&s_wps_rxq)) != NULL) {
140         STAILQ_REMOVE_HEAD(&s_wps_rxq, bqentry);
141         STAILQ_NEXT(param,bqentry) = NULL;
142         os_free(param->buf);
143         os_free(param);
144     }
145     DATA_MUTEX_GIVE();
146 }
147 
148 #ifdef USE_WPS_TASK
wps_task(void * pvParameters)149 void wps_task(void *pvParameters )
150 {
151     ETSEvent *e;
152     wps_ioctl_param_t *param;
153     bool del_task = false;
154 
155     xSemaphoreGive(s_wps_task_create_sem);
156 
157     wpa_printf(MSG_DEBUG, "wps_Task enter");
158     for (;;) {
159         if ( pdPASS == xQueueReceive(s_wps_queue, &e, portMAX_DELAY) ) {
160 
161             if ( (e->sig >= SIG_WPS_ENABLE) && (e->sig < SIG_WPS_NUM) ) {
162                 DATA_MUTEX_TAKE();
163                 if (s_wps_sig_cnt[e->sig]) {
164                     s_wps_sig_cnt[e->sig]--;
165                 } else {
166                     wpa_printf(MSG_ERROR, "wpsT: invalid sig cnt, sig=%d cnt=%d", e->sig, s_wps_sig_cnt[e->sig]);
167                 }
168                 DATA_MUTEX_GIVE();
169             }
170 
171             wpa_printf(MSG_DEBUG, "wpsT: rx sig=%d", e->sig);
172 
173             switch (e->sig) {
174             case SIG_WPS_ENABLE:
175             case SIG_WPS_DISABLE:
176             case SIG_WPS_START:
177                 param = (wps_ioctl_param_t *)e->par;
178                 if (!param) {
179                     wpa_printf(MSG_ERROR, "wpsT: invalid param sig=%d", e->sig);
180                     xSemaphoreGive(s_wps_api_sem);
181                     break;
182                 }
183 
184                 if (e->sig == SIG_WPS_ENABLE) {
185                     param->ret = wifi_wps_enable_internal((esp_wps_config_t *)(param->arg));
186                 } else if (e->sig == SIG_WPS_DISABLE) {
187                     param->ret = wifi_wps_disable_internal();
188                     del_task = true;
189                     s_wps_task_hdl = NULL;
190                 } else {
191                     param->ret = wifi_station_wps_start();
192                 }
193 
194                 xSemaphoreGive(s_wps_api_sem);
195                 break;
196 
197             case SIG_WPS_RX: {
198                 struct wps_rx_param *param = NULL;
199                 while ((param = wps_rxq_dequeue()) != NULL) {
200                     wps_sm_rx_eapol_internal(param->sa, param->buf, param->len);
201                     os_free(param->buf);
202                     os_free(param);
203                 }
204                 break;
205             }
206 
207             case SIG_WPS_TIMER_TIMEOUT:
208                 wifi_station_wps_timeout_internal();
209                 break;
210 
211             case SIG_WPS_TIMER_MSG_TIMEOUT:
212                 wifi_station_wps_msg_timeout_internal();
213                 break;
214 
215             case SIG_WPS_TIMER_SUCCESS_CB:
216                 wifi_station_wps_success_internal();
217                 break;
218 
219             case SIG_WPS_TIMER_SCAN:
220                 wifi_wps_scan_internal();
221                 break;
222 
223             case SIG_WPS_TIMER_EAPOL_START:
224                 wifi_station_wps_eapol_start_handle_internal();
225                 break;
226 
227             default:
228                 wpa_printf(MSG_ERROR, "wpsT: invalid sig=%d", e->sig);
229                 break;
230             }
231             os_free(e);
232 
233             if (del_task) {
234                 wpa_printf(MSG_DEBUG, "wpsT: delete task");
235                 break;
236             }
237         }
238     }
239     vTaskDelete(NULL);
240 }
241 
242 /* wps_post() is thread-safe
243  *
244  */
wps_post(uint32_t sig,uint32_t par)245 int wps_post(uint32_t sig, uint32_t par)
246 {
247     wpa_printf(MSG_DEBUG, "wps post: sig=%d cnt=%d", sig, s_wps_sig_cnt[sig]);
248 
249     DATA_MUTEX_TAKE();
250     if (s_wps_sig_cnt[sig]) {
251         wpa_printf(MSG_DEBUG, "wps post: sig=%d processing", sig);
252         DATA_MUTEX_GIVE();
253         return ESP_OK;
254     } else {
255         ETSEvent *evt = (ETSEvent *)os_malloc(sizeof(ETSEvent));
256 
257         if (evt == NULL) {
258             wpa_printf(MSG_ERROR, "WPS: E N M");
259             DATA_MUTEX_GIVE();
260             return ESP_FAIL;
261         }
262 
263         s_wps_sig_cnt[sig]++;
264         evt->sig = sig;
265         evt->par = par;
266         DATA_MUTEX_GIVE();
267 
268         if ( xQueueSend(s_wps_queue, &evt, 10 / portTICK_PERIOD_MS) != pdPASS) {
269             wpa_printf(MSG_ERROR, "WPS: Q S E");
270             DATA_MUTEX_TAKE();
271             s_wps_sig_cnt[sig]--;
272             DATA_MUTEX_GIVE();
273             return ESP_FAIL;
274         }
275     }
276     return ESP_OK;
277 }
278 #endif
279 
wps_sendto_wrapper(void * buffer,uint16_t len)280 static void wps_sendto_wrapper(void *buffer, uint16_t len)
281 {
282     esp_wifi_internal_tx(WIFI_IF_STA, buffer, len);
283 }
284 
285 /*
286 * wps_sm_ether_send - Send Ethernet frame
287 * @wpa_s: Pointer to wpa_supplicant data
288 * @dest: Destination MAC address
289 * @proto: Ethertype in host byte order
290 * @buf: Frame payload starting from IEEE 802.1X header
291 * @len: Frame payload length
292 * Returns: >=0 on success, <0 on failure
293 */
wps_sm_ether_send(struct wps_sm * sm,const u8 * dest,u16 proto,const u8 * data,size_t data_len)294 static inline int wps_sm_ether_send(struct wps_sm *sm, const u8 *dest, u16 proto,
295                                     const u8 *data, size_t data_len)
296 {
297     void *buffer = (void *)(data - sizeof(struct l2_ethhdr));
298     struct l2_ethhdr *eth = (struct l2_ethhdr *)buffer;
299 
300     os_memcpy(eth->h_dest, dest, ETH_ALEN);
301     os_memcpy(eth->h_source, sm->ownaddr, ETH_ALEN);
302     eth->h_proto = host_to_be16(proto);
303 
304     wps_sendto_wrapper(buffer, sizeof(struct l2_ethhdr) + data_len);
305 
306     return ESP_OK;
307 }
308 
309 
wps_sm_alloc_eapol(struct wps_sm * sm,u8 type,const void * data,u16 data_len,size_t * msg_len,void ** data_pos)310 u8 *wps_sm_alloc_eapol(struct wps_sm *sm, u8 type,
311                        const void *data, u16 data_len,
312                        size_t *msg_len, void **data_pos)
313 {
314     void *buffer;
315     struct ieee802_1x_hdr *hdr;
316 
317     *msg_len = sizeof(struct ieee802_1x_hdr) + data_len;
318     /* XXX: reserve l2_ethhdr is enough */
319     buffer = os_malloc(*msg_len + sizeof(struct l2_ethhdr));
320 
321     if (buffer == NULL) {
322         return NULL;
323     }
324     hdr = (struct ieee802_1x_hdr *)((char *)buffer + sizeof(struct l2_ethhdr));
325 
326     hdr->version = sm->eapol_version;
327     hdr->type = type;
328     hdr->length = host_to_be16(data_len);
329 
330     if (data) {
331         os_memcpy(hdr + 1, data, data_len);
332     } else {
333         os_memset(hdr + 1, 0, data_len);
334     }
335 
336     if (data_pos) {
337         *data_pos = hdr + 1;
338     }
339 
340     return (u8 *) hdr;
341 }
342 
343 
wps_sm_free_eapol(u8 * buffer)344 void wps_sm_free_eapol(u8 *buffer)
345 {
346     if (buffer != NULL) {
347         buffer = buffer - sizeof(struct l2_ethhdr);
348         os_free(buffer);
349     }
350 }
351 
352 
353 /**
354  * wps_init - Initialize WPS Registration protocol data
355  * @cfg: WPS configuration
356  * Returns: Pointer to allocated data or %NULL on failure
357  *
358  * This function is used to initialize WPS data for a registration protocol
359  * instance (i.e., each run of registration protocol as a Registrar of
360  * Enrollee. The caller is responsible for freeing this data after the
361  * registration run has been completed by calling wps_deinit().
362  */
wps_init(void)363 struct wps_data *wps_init(void)
364 {
365     struct wps_sm *sm = gWpsSm;
366     struct wps_data *data = (struct wps_data *)os_zalloc(sizeof(*data));
367     const char *all_zero_pin = "00000000";
368 
369     if (data == NULL) {
370         return NULL;
371     }
372 
373     data->wps = sm->wps_ctx;
374 
375     if (IS_WPS_REGISTRAR(wps_get_type())) {
376         data->registrar = 1;
377     } else {
378         data->registrar = 0;
379     }
380 
381     data->registrar = 0; /* currently, we force to support enrollee only */
382 
383     if (data->registrar) {
384         os_memcpy(data->uuid_r, sm->uuid, WPS_UUID_LEN);
385     } else {
386         os_memcpy(data->mac_addr_e, sm->dev->mac_addr, ETH_ALEN);
387         os_memcpy(data->uuid_e, sm->uuid, WPS_UUID_LEN);
388     }
389 
390     if (wps_get_type() == WPS_TYPE_PIN) {
391         u32 spin = 0;
392         data->dev_pw_id = DEV_PW_DEFAULT;
393         data->dev_password_len = 8;
394         data->dev_password = (u8 *) os_zalloc(data->dev_password_len + 1);
395         if (data->dev_password == NULL) {
396             os_free(data);
397             return NULL;
398         }
399 
400         spin = wps_generate_pin();
401         sprintf((char *)data->dev_password, "%08d", spin);
402         wpa_hexdump_key(MSG_DEBUG, "WPS: AP PIN dev_password",
403                         data->dev_password, data->dev_password_len);
404         do {
405             char tmpp[9];
406             os_bzero(tmpp, 9);
407             os_memcpy(tmpp, data->dev_password, 8);
408             wpa_printf(MSG_DEBUG, "WPS PIN [%s]", tmpp);
409             wifi_event_sta_wps_er_pin_t evt;
410             os_memcpy(evt.pin_code, data->dev_password, 8);
411             esp_event_send_internal(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_PIN, &evt, sizeof(evt), portMAX_DELAY);
412         } while (0);
413     } else if (wps_get_type() == WPS_TYPE_PBC) {
414         data->pbc = 1;
415         /* Use special PIN '00000000' for PBC */
416         data->dev_pw_id = DEV_PW_PUSHBUTTON;
417         if (data->dev_password) {
418             os_free(data->dev_password);
419         }
420         data->dev_password = (u8 *) os_zalloc(9);
421         if (data->dev_password == NULL) {
422             os_free(data);
423             return NULL;
424         } else {
425             strncpy((char *)data->dev_password, all_zero_pin, 9);
426         }
427         data->dev_password_len = 8;
428     }
429 
430 #ifdef CONFIG_WPS_NFC
431     if (cfg->wps->ap && !cfg->registrar && cfg->wps->ap_nfc_dev_pw_id) {
432         data->dev_pw_id = cfg->wps->ap_nfc_dev_pw_id;
433         os_free(data->dev_password);
434         data->dev_password =
435             os_malloc(wpabuf_len(cfg->wps->ap_nfc_dev_pw));
436         if (data->dev_password == NULL) {
437             os_free(data);
438             return NULL;
439         }
440         os_memcpy(data->dev_password,
441                wpabuf_head(cfg->wps->ap_nfc_dev_pw),
442                wpabuf_len(cfg->wps->ap_nfc_dev_pw));
443         data->dev_password_len = wpabuf_len(cfg->wps->ap_nfc_dev_pw);
444     }
445 #endif /* CONFIG_WPS_NFC */
446     data->wps->config_methods = WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_DISPLAY;
447 #ifdef CONFIG_WPS2
448     data->wps->config_methods |= (WPS_CONFIG_VIRT_PUSHBUTTON | WPS_CONFIG_PHY_DISPLAY);
449 #endif
450 
451     data->state = data->registrar ? RECV_M1 : SEND_M1;
452 
453     return data;
454 }
455 
456 
457 /**
458  * wps_deinit - Deinitialize WPS Registration protocol data
459  * @data: WPS Registration protocol data from wps_init()
460  */
wps_deinit(void)461 void wps_deinit(void)
462 {
463     struct wps_data *data = gWpsSm->wps;
464 
465 #ifdef CONFIG_WPS_NFC
466     if (data->registrar && data->nfc_pw_token)
467         wps_registrar_remove_nfc_pw_token(data->wps->registrar,
468                                           data->nfc_pw_token);
469 #endif /* CONFIG_WPS_NFC */
470 
471     if (data->wps_pin_revealed) {
472         wpa_printf(MSG_DEBUG,  "WPS: Full PIN information revealed and "
473                    "negotiation failed");
474     } else if (data->registrar)
475         wpa_printf(MSG_DEBUG,  "WPS: register information revealed and "
476                    "negotiation failed");
477     wpabuf_free(data->dh_privkey);
478 
479 #ifdef DESP32_WORKAROUND
480     /*
481      * due to the public key calculated when wps start, it will not calculate anymore even when we build M1 message, also calculate the key need take a long time
482      * which would cause WPS fail, so we clean the key after WPS finished .
483      */
484     data->dh_privkey = NULL;
485 #endif //DESP32_WORKAROUND
486 
487     wpabuf_free(data->dh_pubkey_e);
488     wpabuf_free(data->dh_pubkey_r);
489     wpabuf_free(data->last_msg);
490     os_free(data->dev_password);
491     dh5_free(data->dh_ctx);
492     wps_dev_deinit(&data->peer_dev);
493 #ifdef CONFIG_WPS_NFC
494     os_free(data->nfc_pw_token);
495 #endif
496     os_free(data);
497 }
498 
499 static void
wps_build_ic_appie_wps_pr(void)500 wps_build_ic_appie_wps_pr(void)
501 {
502     struct wpabuf *extra_ie = NULL;
503     struct wpabuf *wps_ie;
504     struct wps_sm *sm = gWpsSm;
505 
506     wpa_printf(MSG_DEBUG, "wps build: wps pr");
507 
508     if (wps_get_type() == WPS_TYPE_PBC) {
509         wps_ie = (struct wpabuf *)wps_build_probe_req_ie(DEV_PW_PUSHBUTTON,
510                  sm->dev,
511                  sm->uuid, WPS_REQ_ENROLLEE,
512                  0, NULL);
513     } else {
514         wps_ie = (struct wpabuf *)wps_build_probe_req_ie(DEV_PW_DEFAULT,
515                  sm->dev,
516                  sm->uuid, WPS_REQ_ENROLLEE,
517                  0, NULL);
518     }
519 
520     if (!wps_ie) {
521         return;
522     }
523 
524     if (wpabuf_resize(&extra_ie, wpabuf_len(wps_ie)) == 0) {
525         wpabuf_put_buf(extra_ie, wps_ie);
526     } else {
527         wpabuf_free(wps_ie);
528         return;
529     }
530     wpabuf_free(wps_ie);
531 
532     esp_wifi_set_appie_internal(WIFI_APPIE_WPS_PR, (uint8_t *)wpabuf_head(extra_ie), extra_ie->used, 0);
533     wpabuf_free(extra_ie);
534 }
535 
536 static void
wps_build_ic_appie_wps_ar(void)537 wps_build_ic_appie_wps_ar(void)
538 {
539     struct wpabuf *buf = (struct wpabuf *)wps_build_assoc_req_ie(WPS_REQ_ENROLLEE);
540 
541     wpa_printf(MSG_DEBUG, "wps build: wps ar");
542 
543     if (buf) {
544         esp_wifi_set_appie_internal(WIFI_APPIE_WPS_AR, (uint8_t *)wpabuf_head(buf), buf->used, 0);
545         wpabuf_free(buf);
546     }
547 }
548 
549 static bool
wps_parse_scan_result(struct wps_scan_ie * scan)550 wps_parse_scan_result(struct wps_scan_ie *scan)
551 {
552     struct wps_sm *sm = gWpsSm;
553     wifi_mode_t op_mode = 0;
554 #ifdef WPS_DEBUG
555     char tmp[32];
556 
557     os_bzero(tmp, 32);
558     strncpy(tmp, (char *)&scan->ssid[2], (int)scan->ssid[1]);
559     wpa_printf(MSG_DEBUG, "wps parse scan: %s", tmp);
560 #endif
561 
562     if (!sm->is_wps_scan || !scan->bssid) {
563         return false;
564     }
565 
566     if (wps_get_type() == WPS_TYPE_DISABLE
567             || (wps_get_status() != WPS_STATUS_DISABLE
568                 && wps_get_status() != WPS_STATUS_SCANNING)
569        ) {
570         return false;
571     }
572 
573     if (!scan->rsn && !scan->wpa && (scan->capinfo & WIFI_CAPINFO_PRIVACY)) {
574         wpa_printf(MSG_INFO, "WEP not suppported in WPS");
575         return false;
576     }
577 
578     if (sm->wps_pin_war) {
579         /* We have selected candidate for this scan */
580         return false;
581     }
582 
583     esp_wifi_get_mode(&op_mode);
584     if ((op_mode == WIFI_MODE_STA
585 #ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
586     || op_mode == WIFI_MODE_APSTA
587 #endif
588     ) && scan->wps) {
589         bool ap_found = false;
590         struct wpabuf *buf = wpabuf_alloc_copy(scan->wps + 6, scan->wps[1] - 4);
591         int count;
592 
593         if ((wps_get_type() == WPS_TYPE_PBC && wps_is_selected_pbc_registrar(buf)) ||
594             (wps_get_type() == WPS_TYPE_PIN && wps_is_addr_authorized(buf, sm->ownaddr, 1))) {
595             /* Found one AP with selected registrar true */
596             sm->ignore_sel_reg = false;
597             sm->discard_ap_cnt = 0;
598             ap_found = true;
599         }
600         if ((op_mode == WIFI_MODE_STA
601 #ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
602             || op_mode == WIFI_MODE_APSTA
603 #endif
604             ) && wps_get_type() == WPS_TYPE_PIN && sm->ignore_sel_reg) {
605             /* AP is in discard list? */
606             for (count = 0; count < WPS_MAX_DIS_AP_NUM; count++) {
607                 if (os_memcmp(sm->dis_ap_list[count].bssid, scan->bssid, ETH_ALEN) == 0) {
608                     wpa_printf(MSG_INFO, "discard ap bssid "MACSTR, MAC2STR(scan->bssid));
609                     return false;
610                 }
611             }
612             sm->wps_pin_war = true;
613         }
614 
615         if (ap_found || sm->wps_pin_war) {
616             wpabuf_free(buf);
617             esp_wifi_enable_sta_privacy_internal();
618             os_memset(sm->config.ssid, 0, sizeof(sm->config.ssid));
619             strncpy((char *)sm->config.ssid, (char *)&scan->ssid[2], (int)scan->ssid[1]);
620             if (scan->bssid && memcmp(sm->config.bssid, scan->bssid, ETH_ALEN) != 0) {
621                 printf("sm BSSid: "MACSTR " scan BSSID " MACSTR "\n", MAC2STR(sm->config.bssid), MAC2STR(scan->bssid));
622                 sm->discover_ssid_cnt++;
623                 os_memcpy(sm->bssid, scan->bssid, ETH_ALEN);
624                 os_memcpy(sm->config.bssid, scan->bssid, ETH_ALEN);
625                 sm->config.bssid_set = 1;
626             }
627             wpa_printf(MSG_DEBUG, "wps discover [%s]", (char *)sm->config.ssid);
628             sm->channel = scan->chan;
629 
630             return true;
631         }
632         wpabuf_free(buf);
633     }
634 
635     return false;
636 }
637 
wps_send_eap_identity_rsp(u8 id)638 int wps_send_eap_identity_rsp(u8 id)
639 {
640     struct wps_sm *sm = gWpsSm;
641     struct wpabuf *eap_buf = NULL;
642     u8 bssid[6];
643     u8 *buf = NULL;
644     int len;
645     int ret = ESP_OK;
646 
647     wpa_printf(MSG_DEBUG, "wps send eapol id rsp");
648     eap_buf = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY, sm->identity_len,
649                             EAP_CODE_RESPONSE, id);
650     if (!eap_buf) {
651         ret = ESP_FAIL;
652         goto _err;
653     }
654 
655     ret = esp_wifi_get_assoc_bssid_internal(bssid);
656     if (ret != 0) {
657         wpa_printf(MSG_ERROR, "bssid is empty!");
658         ret = ESP_FAIL;
659         goto _err;
660     }
661 
662     wpabuf_put_data(eap_buf, sm->identity, sm->identity_len);
663 
664     buf = wps_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAP_PACKET, wpabuf_head_u8(eap_buf), wpabuf_len(eap_buf), (size_t *)&len, NULL);
665     if (!buf) {
666         ret = ESP_ERR_NO_MEM;
667         goto _err;
668     }
669 
670     ret = wps_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len);
671     if (ret) {
672         ret = ESP_FAIL;
673         goto _err;
674     }
675 
676 _err:
677     wps_sm_free_eapol(buf);
678     wpabuf_free(eap_buf);
679     return ret;
680 }
681 
wps_send_frag_ack(u8 id)682 int wps_send_frag_ack(u8 id)
683 {
684     struct wps_sm *sm = gWpsSm;
685     struct wpabuf *eap_buf = NULL;
686     u8 bssid[6];
687     u8 *buf;
688     int len;
689     int ret = 0;
690     enum wsc_op_code opcode = WSC_FRAG_ACK;
691 
692     wpa_printf(MSG_DEBUG, "send frag ack id:%d", id);
693 
694     if (!sm) {
695         return ESP_FAIL;
696     }
697 
698     ret = esp_wifi_get_assoc_bssid_internal(bssid);
699     if (ret != 0) {
700         wpa_printf(MSG_ERROR, "bssid is empty!");
701         return ret;
702     }
703 
704     eap_buf = eap_msg_alloc(EAP_VENDOR_WFA, 0x00000001, 2, EAP_CODE_RESPONSE, id);
705     if (!eap_buf) {
706         ret = ESP_ERR_NO_MEM;
707         goto _err;
708     }
709 
710     wpabuf_put_u8(eap_buf, opcode);
711     wpabuf_put_u8(eap_buf, 0x00); /* flags */
712 
713     buf = wps_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAP_PACKET, wpabuf_head_u8(eap_buf), wpabuf_len(eap_buf), (size_t *)&len, NULL);
714     if (!buf) {
715         ret = ESP_ERR_NO_MEM;
716         goto _err;
717     }
718 
719     ret = wps_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len);
720     wps_sm_free_eapol(buf);
721     if (ret) {
722         ret = ESP_ERR_NO_MEM;
723         goto _err;
724     }
725 
726 _err:
727     wpabuf_free(eap_buf);
728     return ret;
729 }
730 
wps_enrollee_process_msg_frag(struct wpabuf ** buf,int tot_len,u8 * frag_data,int frag_len,u8 flag)731 int wps_enrollee_process_msg_frag(struct wpabuf **buf, int tot_len, u8 *frag_data, int frag_len, u8 flag)
732 {
733     struct wps_sm *sm = gWpsSm;
734     u8 identifier;
735 
736     if (!sm) {
737         return ESP_FAIL;
738     }
739 
740     identifier = sm->current_identifier;
741 
742     if (buf == NULL || frag_data == NULL) {
743         wpa_printf(MSG_ERROR, "fun:%s. line:%d, frag buf or frag data is null", __FUNCTION__, __LINE__);
744         return ESP_FAIL;
745     }
746 
747     if (*buf == NULL) {
748         if (0 == (flag & WPS_MSG_FLAG_LEN) || tot_len < frag_len) {
749             wpa_printf(MSG_ERROR, "fun:%s. line:%d, flag error:%02x", __FUNCTION__, __LINE__, flag);
750             return ESP_FAIL;
751         }
752 
753         *buf = wpabuf_alloc(tot_len);
754         if (*buf == NULL) {
755             return ESP_ERR_NO_MEM;
756         }
757 
758         wpabuf_put_data(*buf, frag_data, frag_len);
759         return wps_send_frag_ack(identifier);
760     }
761 
762     if (flag & WPS_MSG_FLAG_LEN) {
763         wpa_printf(MSG_ERROR, "fun:%s. line:%d, flag error:%02x", __FUNCTION__, __LINE__, flag);
764         return ESP_FAIL;
765     }
766 
767     wpabuf_put_data(*buf, frag_data, frag_len);
768 
769     if (flag & WPS_MSG_FLAG_MORE) {
770         return wps_send_frag_ack(identifier);
771     }
772 
773     return ESP_OK;
774 }
775 
wps_process_wps_mX_req(u8 * ubuf,int len,enum wps_process_res * res)776 int wps_process_wps_mX_req(u8 *ubuf, int len, enum wps_process_res *res)
777 {
778     struct wps_sm *sm = gWpsSm;
779     static struct wpabuf *wps_buf = NULL;
780     struct eap_expand *expd;
781     int tlen = 0;
782     u8 *tbuf;
783     u8 flag;
784     int frag_len;
785     u16 be_tot_len = 0;
786 
787     if (!sm) {
788         return ESP_FAIL;
789     }
790 
791     expd = (struct eap_expand *) ubuf;
792     wpa_printf(MSG_DEBUG, "wps process mX req: len %d, tlen %d", len, tlen);
793 
794     flag = *(u8 *)(ubuf + sizeof(struct eap_expand));
795     if (flag & WPS_MSG_FLAG_LEN) {
796         tbuf = ubuf + sizeof(struct eap_expand) + 1 + 2;//two bytes total length
797         frag_len = len - (sizeof(struct eap_expand) + 1 + 2);
798         be_tot_len = *(u16 *)(ubuf + sizeof(struct eap_expand) + 1);
799         tlen = ((be_tot_len & 0xff) << 8) | ((be_tot_len >> 8) & 0xff);
800     } else {
801         tbuf = ubuf + sizeof(struct eap_expand) + 1;
802         frag_len = len - (sizeof(struct eap_expand) + 1);
803         tlen = frag_len;
804     }
805 
806     if ((flag & WPS_MSG_FLAG_MORE) || wps_buf != NULL) {//frag msg
807         wpa_printf(MSG_DEBUG, "rx frag msg id:%d, flag:%d, frag_len: %d, tot_len: %d, be_tot_len:%d", sm->current_identifier, flag, frag_len, tlen, be_tot_len);
808         if (ESP_OK != wps_enrollee_process_msg_frag(&wps_buf, tlen, tbuf, frag_len, flag)) {
809             if (wps_buf) {
810                 wpabuf_free(wps_buf);
811                 wps_buf = NULL;
812             }
813             return ESP_FAIL;
814         }
815         if (flag & WPS_MSG_FLAG_MORE) {
816             if (res) {
817                 *res = WPS_FRAGMENT;
818             }
819             return ESP_OK;
820         }
821     } else { //not frag msg
822         if (wps_buf) {//if something wrong, frag msg buf is not freed, free first
823             wpa_printf(MSG_ERROR, "something is wrong, frag buf is not freed");
824             wpabuf_free(wps_buf);
825             wps_buf = NULL;
826         }
827         wps_buf = wpabuf_alloc_copy(tbuf, tlen);
828     }
829 
830     if (!wps_buf) {
831         return ESP_FAIL;
832     }
833 
834     ets_timer_disarm(&sm->wps_msg_timeout_timer);
835 
836     if (res) {
837         *res = wps_enrollee_process_msg(sm->wps, expd->opcode, wps_buf);
838     } else {
839         wps_enrollee_process_msg(sm->wps, expd->opcode, wps_buf);
840     }
841 
842     if (wps_buf) {
843         wpabuf_free(wps_buf);
844         wps_buf = NULL;
845     }
846     return ESP_OK;
847 }
848 
wps_send_wps_mX_rsp(u8 id)849 int wps_send_wps_mX_rsp(u8 id)
850 {
851     struct wps_sm *sm = gWpsSm;
852     struct wpabuf *eap_buf = NULL;
853     struct wpabuf *wps_buf = NULL;
854     u8 bssid[6];
855     u8 *buf;
856     int len;
857     int ret = 0;
858     enum wsc_op_code opcode;
859 
860     wpa_printf(MSG_DEBUG, "wps send wps mX rsp");
861 
862     if (!sm) {
863         return ESP_FAIL;
864     }
865 
866     ret = esp_wifi_get_assoc_bssid_internal(bssid);
867     if (ret != 0) {
868         wpa_printf(MSG_ERROR, "bssid is empty!");
869         return ret;
870     }
871 
872     wps_buf = (struct wpabuf *)wps_enrollee_get_msg(sm->wps, &opcode);
873     if (!wps_buf) {
874         ret = ESP_FAIL;
875         goto _err;
876     }
877 
878     eap_buf = eap_msg_alloc(EAP_VENDOR_WFA, 0x00000001, wpabuf_len(wps_buf) + 2, EAP_CODE_RESPONSE, id);
879     if (!eap_buf) {
880         ret = ESP_FAIL;
881         goto _err;
882     }
883 
884     wpabuf_put_u8(eap_buf, opcode);
885     wpabuf_put_u8(eap_buf, 0x00); /* flags */
886     wpabuf_put_data(eap_buf, wpabuf_head_u8(wps_buf), wpabuf_len(wps_buf));
887 
888 
889     wpabuf_free(wps_buf);
890 
891     buf = wps_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAP_PACKET, wpabuf_head_u8(eap_buf), wpabuf_len(eap_buf), (size_t *)&len, NULL);
892     if (!buf) {
893         ret = ESP_FAIL;
894         goto _err;
895     }
896 
897     ret = wps_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len);
898     wps_sm_free_eapol(buf);
899     if (ret) {
900         ret = ESP_FAIL;
901         goto _err;
902     }
903 
904 _err:
905     wpabuf_free(eap_buf);
906     return ret;
907 }
908 
909 
910 
wps_tx_start(void)911 int wps_tx_start(void)
912 {
913     struct wps_sm *sm = gWpsSm;
914     u8 bssid[6];
915     u8 *buf;
916     int len;
917     int ret = 0;
918 
919     ret = esp_wifi_get_assoc_bssid_internal(bssid);
920     if (ret != 0) {
921         wpa_printf(MSG_ERROR, "bssid is empty!");
922         return ret;
923     }
924 
925     if (!sm) {
926         return ESP_FAIL;
927     }
928 
929     wpa_printf(MSG_DEBUG,  "WPS: Send EAPOL START.");
930     buf = wps_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START, (u8 *)"", 0, (size_t *)&len, NULL);
931     if (!buf) {
932         return ESP_ERR_NO_MEM;
933     }
934 
935     wps_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len);
936     wps_sm_free_eapol(buf);
937 
938     ets_timer_arm(&sm->wps_eapol_start_timer, 3000, 0);
939 
940     return ESP_OK;
941 }
942 
wps_start_pending(void)943 int wps_start_pending(void)
944 {
945     if (!gWpsSm) {
946         return ESP_FAIL;
947     }
948 
949     wpa_printf(MSG_DEBUG, "wps start pending");
950     return wps_tx_start();
951 }
952 
wps_stop_process(wifi_event_sta_wps_fail_reason_t reason_code)953 int wps_stop_process(wifi_event_sta_wps_fail_reason_t reason_code)
954 {
955     struct wps_sm *sm = gWpsSm;
956 
957     if (!gWpsSm) {
958         return ESP_FAIL;
959     }
960 
961     wps_set_status(WPS_STATUS_DISABLE);
962     sm->scan_cnt = 0;
963     sm->discover_ssid_cnt = 0;
964     sm->wps->state = SEND_M1;
965     os_bzero(sm->bssid, ETH_ALEN);
966     os_bzero(sm->ssid, sizeof(sm->ssid));
967     os_bzero(sm->ssid_len, sizeof(sm->ssid_len));
968     os_bzero((u8 *)&sm->config, sizeof(wifi_sta_config_t));
969     sm->ap_cred_cnt = 0;
970 
971     esp_wifi_disarm_sta_connection_timer_internal();
972     ets_timer_disarm(&sm->wps_msg_timeout_timer);
973     ets_timer_disarm(&sm->wps_success_cb_timer);
974 
975     esp_wifi_disconnect();
976 
977     wpa_printf(MSG_DEBUG, "Write wps_fail_information");
978 
979     esp_event_send_internal(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_FAILED, &reason_code, sizeof(reason_code), portMAX_DELAY);
980 
981     return ESP_OK;
982 }
983 
wps_finish(void)984 int wps_finish(void)
985 {
986     struct wps_sm *sm = gWpsSm;
987     int ret = ESP_FAIL;
988 
989     if (!gWpsSm) {
990         return ESP_FAIL;
991     }
992 
993     if (sm->wps->state == WPS_FINISHED) {
994 
995         wpa_printf(MSG_DEBUG, "wps finished------>");
996         wps_set_status(WPS_STATUS_SUCCESS);
997         esp_wifi_disarm_sta_connection_timer_internal();
998         ets_timer_disarm(&sm->wps_timeout_timer);
999         ets_timer_disarm(&sm->wps_msg_timeout_timer);
1000 
1001         if (sm->ap_cred_cnt == 1) {
1002             wifi_config_t *config = (wifi_config_t *)os_zalloc(sizeof(wifi_config_t));
1003 
1004             if (config == NULL) {
1005                 wifi_event_sta_wps_fail_reason_t reason_code = WPS_FAIL_REASON_NORMAL;
1006                 esp_event_send_internal(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_FAILED, &reason_code, sizeof(reason_code), portMAX_DELAY);
1007                 return ESP_FAIL;
1008             }
1009 
1010             os_memset(config, 0x00, sizeof(wifi_sta_config_t));
1011             os_memcpy(config->sta.ssid, sm->ssid[0], sm->ssid_len[0]);
1012             os_memcpy(config->sta.password, sm->key[0], sm->key_len[0]);
1013             os_memcpy(config->sta.bssid, sm->bssid, ETH_ALEN);
1014             config->sta.bssid_set = 0;
1015             esp_wifi_set_config(0, config);
1016 
1017             os_free(config);
1018             config = NULL;
1019         }
1020         ets_timer_disarm(&sm->wps_success_cb_timer);
1021         ets_timer_arm(&sm->wps_success_cb_timer, 1000, 0);
1022 
1023         ret = 0;
1024     } else {
1025         wpa_printf(MSG_ERROR, "wps failed-----> wps_pin_war=%d", sm->wps_pin_war);
1026         if (sm->wps_pin_war) {
1027             sm->discover_ssid_cnt = 0;
1028             esp_wifi_disconnect();
1029             os_bzero(sm->ssid, sizeof(sm->ssid));
1030             os_bzero(sm->ssid_len, sizeof(sm->ssid_len));
1031             wps_add_discard_ap(sm->config.bssid);
1032         } else {
1033             ret = wps_stop_process(WPS_FAIL_REASON_NORMAL);
1034         }
1035     }
1036 
1037     return ret;
1038 }
1039 
1040 /* Add current ap to discard ap list */
wps_add_discard_ap(u8 * bssid)1041 void wps_add_discard_ap(u8 *bssid)
1042 {
1043     struct wps_sm *sm = gWpsSm;
1044     u8 cnt = sm->discard_ap_cnt;
1045 
1046     if (!gWpsSm || !bssid) {
1047         return;
1048     }
1049 
1050     if (sm->discard_ap_cnt < WPS_MAX_DIS_AP_NUM) {
1051         sm->discard_ap_cnt++;
1052     } else {
1053         for (cnt = 0; cnt < WPS_MAX_DIS_AP_NUM - 2; cnt++) {
1054             os_memcpy(sm->dis_ap_list[cnt].bssid, sm->dis_ap_list[cnt + 1].bssid, 6);
1055         }
1056         sm->discard_ap_cnt = WPS_MAX_DIS_AP_NUM;
1057     }
1058     os_memcpy(sm->dis_ap_list[cnt].bssid, bssid, 6);
1059     wpa_printf(MSG_INFO, "Added BSSID:"MACSTR" to discard list cnt=%d" , MAC2STR(bssid), sm->discard_ap_cnt);
1060 }
1061 
wps_start_msg_timer(void)1062 int wps_start_msg_timer(void)
1063 {
1064     struct wps_sm *sm = gWpsSm;
1065     uint32_t msg_timeout;
1066     int ret = ESP_FAIL;
1067 
1068     if (!gWpsSm) {
1069         return ESP_FAIL;
1070     }
1071 
1072     if (sm->wps->state == WPS_FINISHED) {
1073         msg_timeout = 100;
1074         wpa_printf(MSG_DEBUG, "start msg timer WPS_FINISHED %d ms", msg_timeout);
1075         ets_timer_disarm(&sm->wps_msg_timeout_timer);
1076         ets_timer_arm(&sm->wps_msg_timeout_timer, msg_timeout, 0);
1077         ret = 0;
1078     } else if (sm->wps->state == RECV_M2) {
1079         msg_timeout = 5000;
1080         wpa_printf(MSG_DEBUG, "start msg timer RECV_M2 %d ms", msg_timeout);
1081         ets_timer_disarm(&sm->wps_msg_timeout_timer);
1082         ets_timer_arm(&sm->wps_msg_timeout_timer, msg_timeout, 0);
1083         ret = 0;
1084     }
1085     return ret;
1086 }
1087 
1088 /**
1089  * wps_sm_rx_eapol - Process received WPA EAPOL frames
1090  * @sm: Pointer to WPA state machine data from wpa_sm_init()
1091  * @src_addr: Source MAC address of the EAPOL packet
1092  * @buf: Pointer to the beginning of the EAPOL data (EAPOL header)
1093  * @len: Length of the EAPOL frame
1094  * Returns: 1 = WPA EAPOL-Key processed, ESP_OK = not a WPA EAPOL-Key, ESP_FAIL failure
1095  *
1096  * This function is called for each received EAPOL frame. Other than EAPOL-Key
1097  * frames can be skipped if filtering is done elsewhere. wpa_sm_rx_eapol() is
1098  * only processing WPA and WPA2 EAPOL-Key frames.
1099  *
1100  * The received EAPOL-Key packets are validated and valid packets are replied
1101  * to. In addition, key material (PTK, GTK) is configured at the end of a
1102  * successful key handshake.
1103  * buf begin from version, so remove mac header ,snap header and ether_type
1104  */
wps_sm_rx_eapol(u8 * src_addr,u8 * buf,u32 len)1105 int wps_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len)
1106 {
1107     if (!gWpsSm) {
1108         return ESP_FAIL;
1109     }
1110 
1111 #ifdef USE_WPS_TASK
1112     {
1113         struct wps_rx_param *param = (struct wps_rx_param *)os_zalloc(sizeof(struct wps_rx_param));   /* free in task */
1114 
1115         if (!param) {
1116             return ESP_ERR_NO_MEM;
1117         }
1118 
1119         param->buf = (u8 *)os_zalloc(len);   /* free in task */
1120         if (!param->buf) {
1121             os_free(param);
1122             return ESP_ERR_NO_MEM;
1123         }
1124         os_memcpy(param->buf, buf, len);
1125         param->len = len;
1126         os_memcpy(param->sa, src_addr, WPS_ADDR_LEN);
1127 
1128         wps_rxq_enqueue(param);
1129         return wps_post(SIG_WPS_RX, 0);
1130     }
1131 #else
1132     return wps_sm_rx_eapol_internal(src_addr, buf, len);
1133 #endif
1134 }
1135 
wps_sm_rx_eapol_internal(u8 * src_addr,u8 * buf,u32 len)1136 int wps_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len)
1137 {
1138     struct wps_sm *sm = gWpsSm;
1139     u32 plen, data_len, eap_len;
1140     struct ieee802_1x_hdr *hdr;
1141     struct eap_hdr *ehdr;
1142     u8 *tmp;
1143     u8 eap_code;
1144     u8 eap_type;
1145     int ret = ESP_FAIL;
1146     enum wps_process_res res = WPS_DONE;
1147 
1148     if (!gWpsSm) {
1149         return ESP_FAIL;
1150     }
1151 
1152     if (len < sizeof(*hdr) + sizeof(*ehdr)) {
1153 #ifdef DEBUG_PRINT
1154         wpa_printf(MSG_DEBUG,  "WPA: EAPOL frame too short to be a WPA "
1155                    "EAPOL-Key (len %lu, expecting at least %lu)",
1156                    (unsigned long) len,
1157                    (unsigned long) sizeof(*hdr) + sizeof(*ehdr));
1158 #endif
1159         return ESP_OK;
1160     }
1161 
1162     tmp = buf;
1163 
1164     hdr = (struct ieee802_1x_hdr *) tmp;
1165     ehdr = (struct eap_hdr *) (hdr + 1);
1166     plen = be_to_host16(hdr->length);
1167     data_len = plen + sizeof(*hdr);
1168     eap_len = be_to_host16(ehdr->length);
1169 
1170 #ifdef DEBUG_PRINT
1171     wpa_printf(MSG_DEBUG, "IEEE 802.1X RX: version=%d type=%d length=%d",
1172                hdr->version, hdr->type, plen);
1173 #endif
1174 
1175     if (hdr->version < EAPOL_VERSION) {
1176         /* TODO: backwards compatibility */
1177     }
1178     if (hdr->type != IEEE802_1X_TYPE_EAP_PACKET) {
1179 #ifdef DEBUG_PRINT
1180         wpa_printf(MSG_DEBUG, "WPS: EAP frame (type %u) discarded, "
1181                    "not a EAP PACKET frame", hdr->type);
1182 #endif
1183         ret = 0;
1184         goto out;
1185     }
1186     if (plen > len - sizeof(*hdr) || plen < sizeof(*ehdr)) {
1187 #ifdef DEBUG_PRINT
1188         wpa_printf(MSG_DEBUG, "WPA: EAPOL frame payload size %lu "
1189                    "invalid (frame size %lu)",
1190                    (unsigned long) plen, (unsigned long) len);
1191 #endif
1192         ret = 0;
1193         goto out;
1194     }
1195 
1196     wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL-EAP PACKET", tmp, len);
1197 
1198     if (data_len < len) {
1199 #ifdef DEBUG_PRINT
1200         wpa_printf(MSG_DEBUG, "WPA: ignoring %lu bytes after the IEEE "
1201                    "802.1X data", (unsigned long) len - data_len);
1202 #endif
1203     }
1204 
1205     if (eap_len != plen) {
1206 #ifdef DEBUG_PRINT
1207         wpa_printf(MSG_DEBUG, "WPA: EAPOL length %lu "
1208                    "invalid (eapol length %lu)",
1209                    (unsigned long) eap_len, (unsigned long) plen);
1210 #endif
1211         ret = 0;
1212         goto out;
1213     }
1214 
1215     eap_code = ehdr->code;
1216     switch (eap_code) {
1217     case EAP_CODE_SUCCESS:
1218         wpa_printf(MSG_DEBUG, "error: receive eapol success frame!");
1219         ret = 0;
1220         break;
1221     case EAP_CODE_FAILURE:
1222         wpa_printf(MSG_DEBUG, "receive eap code failure!");
1223         ret = wps_finish();
1224         break;
1225     case EAP_CODE_RESPONSE:
1226         wpa_printf(MSG_DEBUG, "error: receive eapol response frame!");
1227         ret = 0;
1228         break;
1229     case EAP_CODE_REQUEST: {
1230         eap_type = ((u8 *)ehdr)[sizeof(*ehdr)];
1231         switch (eap_type) {
1232         case EAP_TYPE_IDENTITY:
1233             wpa_printf(MSG_DEBUG, "=========identity===========");
1234             sm->current_identifier = ehdr->identifier;
1235             ets_timer_disarm(&sm->wps_eapol_start_timer);
1236             wpa_printf(MSG_DEBUG,  "WPS: Build EAP Identity.");
1237             ret = wps_send_eap_identity_rsp(ehdr->identifier);
1238             ets_timer_arm(&sm->wps_eapol_start_timer, 3000, 0);
1239             break;
1240         case EAP_TYPE_EXPANDED:
1241             wpa_printf(MSG_DEBUG, "=========expanded plen[%d], %d===========", plen, sizeof(*ehdr));
1242             if (ehdr->identifier == sm->current_identifier) {
1243                 ret = 0;
1244                 wpa_printf(MSG_DEBUG, "wps: ignore overlap identifier");
1245                 goto out;
1246             }
1247             sm->current_identifier = ehdr->identifier;
1248 
1249             tmp = (u8 *)(ehdr + 1) + 1;
1250             ret = wps_process_wps_mX_req(tmp, plen - sizeof(*ehdr) - 1, &res);
1251             if (ret == 0 && res != WPS_FAILURE && res != WPS_IGNORE && res != WPS_FRAGMENT) {
1252                 ret = wps_send_wps_mX_rsp(ehdr->identifier);
1253                 if (ret == 0) {
1254                     wpa_printf(MSG_DEBUG, "sm->wps->state = %d", sm->wps->state);
1255                     wps_start_msg_timer();
1256                 }
1257             } else if (ret == 0 && res == WPS_FRAGMENT) {
1258                 wpa_printf(MSG_DEBUG, "wps frag, continue...");
1259                 ret = ESP_OK;
1260             } else if (res == WPS_IGNORE) {
1261                 wpa_printf(MSG_DEBUG, "IGNORE overlap Mx");
1262                 ret = ESP_OK; /* IGNORE the overlap */
1263             } else {
1264                 ret = ESP_FAIL;
1265             }
1266             break;
1267         default:
1268             break;
1269         }
1270         break;
1271     }
1272     default:
1273         break;
1274     }
1275 out:
1276     if (ret != 0 && sm->wps_pin_war) {
1277         sm->wps_pin_war = false;
1278         wifi_wps_scan();
1279     } else if ((ret != 0 || res == WPS_FAILURE)) {
1280         wifi_event_sta_wps_fail_reason_t reason_code = WPS_FAIL_REASON_NORMAL;
1281         wpa_printf(MSG_DEBUG, "wpa rx eapol internal: fail ret=%d", ret);
1282         wps_set_status(WPS_STATUS_DISABLE);
1283         esp_wifi_disarm_sta_connection_timer_internal();
1284         ets_timer_disarm(&sm->wps_timeout_timer);
1285 
1286         esp_event_send_internal(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_FAILED, &reason_code, sizeof(reason_code), portMAX_DELAY);
1287 
1288         return ret;
1289     }
1290 
1291     return ret;
1292 }
1293 
wps_set_default_factory(void)1294 int wps_set_default_factory(void)
1295 {
1296     if (!s_factory_info) {
1297         s_factory_info = os_zalloc(sizeof(wps_factory_information_t));
1298         if (!s_factory_info) {
1299             wpa_printf(MSG_ERROR, "wps factory info malloc failed");
1300             return ESP_ERR_NO_MEM;
1301         }
1302     }
1303 
1304     sprintf(s_factory_info->manufacturer, "ESPRESSIF");
1305     sprintf(s_factory_info->model_name, "ESPRESSIF IOT");
1306     sprintf(s_factory_info->model_number, "ESP32");
1307     sprintf(s_factory_info->device_name, "ESP32 STATION");
1308 
1309     return ESP_OK;
1310 }
1311 
wps_set_factory_info(const esp_wps_config_t * config)1312 int wps_set_factory_info(const esp_wps_config_t *config)
1313 {
1314     int ret;
1315 
1316     ret = wps_set_default_factory();
1317     if (ret != 0) {
1318         return ret;
1319     }
1320 
1321     if (config->factory_info.manufacturer[0] != 0) {
1322         os_memcpy(s_factory_info->manufacturer, config->factory_info.manufacturer, WPS_MAX_MANUFACTURER_LEN - 1);
1323     }
1324 
1325     if (config->factory_info.model_number[0] != 0) {
1326         os_memcpy(s_factory_info->model_number, config->factory_info.model_number, WPS_MAX_MODEL_NUMBER_LEN - 1);
1327     }
1328 
1329     if (config->factory_info.model_name[0] != 0) {
1330         os_memcpy(s_factory_info->model_name, config->factory_info.model_name, WPS_MAX_MODEL_NAME_LEN - 1);
1331     }
1332 
1333     if (config->factory_info.device_name[0] != 0) {
1334         os_memcpy(s_factory_info->device_name, config->factory_info.device_name, WPS_MAX_DEVICE_NAME_LEN - 1);
1335     }
1336 
1337     wpa_printf(MSG_INFO, "manufacturer: %s, model number: %s, model name: %s, device name: %s", s_factory_info->manufacturer,
1338                s_factory_info->model_number, s_factory_info->model_name, s_factory_info->device_name);
1339 
1340     return ESP_OK;
1341 }
1342 
1343 
wps_dev_init(void)1344 int wps_dev_init(void)
1345 {
1346     int ret = 0;
1347     struct wps_sm *sm = gWpsSm;
1348     struct wps_device_data *dev = NULL;
1349 
1350     if (!sm) {
1351         ret = ESP_FAIL;
1352         goto _out;
1353     }
1354 
1355     dev = &sm->wps_ctx->dev;
1356     sm->dev = dev;
1357 
1358     if (!dev) {
1359         ret = ESP_FAIL;
1360         goto _out;
1361     }
1362     dev->config_methods = WPS_CONFIG_VIRT_PUSHBUTTON | WPS_CONFIG_PHY_DISPLAY;
1363     dev->rf_bands = WPS_RF_24GHZ;
1364 
1365     WPA_PUT_BE16(dev->pri_dev_type, WPS_DEV_PHONE);
1366     WPA_PUT_BE32(dev->pri_dev_type + 2, WPS_DEV_OUI_WFA);
1367     WPA_PUT_BE16(dev->pri_dev_type + 6, WPS_DEV_PHONE_SINGLE_MODE);
1368 
1369     if (!s_factory_info) {
1370         ret = wps_set_default_factory();
1371         if (ret != 0) {
1372             goto _out;
1373         }
1374     }
1375 
1376     dev->manufacturer = (char *)os_zalloc(WPS_MAX_MANUFACTURER_LEN);
1377     if (!dev->manufacturer) {
1378         ret = ESP_FAIL;
1379         goto _out;
1380     }
1381     sprintf(dev->manufacturer, s_factory_info->manufacturer);
1382 
1383     dev->model_name = (char *)os_zalloc(WPS_MAX_MODEL_NAME_LEN);
1384     if (!dev->model_name) {
1385         ret = ESP_FAIL;
1386         goto _out;
1387     }
1388     sprintf(dev->model_name, s_factory_info->model_name);
1389 
1390     dev->model_number = (char *)os_zalloc(WPS_MAX_MODEL_NAME_LEN);
1391     if (!dev->model_number) {
1392         ret = ESP_FAIL;
1393         goto _out;
1394     }
1395     sprintf(dev->model_number, s_factory_info->model_number);
1396 
1397     dev->device_name = (char *)os_zalloc(WPS_MAX_DEVICE_NAME_LEN);
1398     if (!dev->device_name) {
1399         ret = ESP_FAIL;
1400         goto _out;
1401     }
1402     sprintf(dev->device_name, s_factory_info->device_name);
1403 
1404     dev->serial_number = (char *)os_zalloc(16);
1405     if (!dev->serial_number) {
1406         ret = ESP_FAIL;
1407         goto _out;
1408     }
1409     sprintf(dev->serial_number, "%02x%02x%02x%02x%02x%02x",
1410             sm->ownaddr[0], sm->ownaddr[1], sm->ownaddr[2],
1411             sm->ownaddr[3], sm->ownaddr[4], sm->ownaddr[5]);
1412 
1413     uuid_gen_mac_addr(sm->ownaddr, sm->uuid);
1414     os_memcpy(dev->mac_addr, sm->ownaddr, ETH_ALEN);
1415 
1416     return ESP_OK;
1417 
1418 _out:
1419     if (!dev) {
1420         return ret;
1421     }
1422     if (dev->manufacturer) {
1423         os_free(dev->manufacturer);
1424     }
1425     if (dev->model_name) {
1426         os_free(dev->model_name);
1427     }
1428     if (dev->model_number) {
1429         os_free(dev->model_number);
1430     }
1431     if (dev->device_name) {
1432         os_free(dev->device_name);
1433     }
1434     if (dev->serial_number) {
1435         os_free(dev->serial_number);
1436     }
1437 
1438     if (s_factory_info) {
1439         os_free(s_factory_info);
1440         s_factory_info = NULL;
1441     }
1442 
1443     return ret;
1444 }
1445 
1446 
wps_dev_deinit(struct wps_device_data * dev)1447 int wps_dev_deinit(struct wps_device_data *dev)
1448 {
1449     int ret = 0;
1450 
1451     if (!dev) {
1452         return ESP_FAIL;
1453     }
1454 
1455     if (dev->manufacturer) {
1456         os_free(dev->manufacturer);
1457     }
1458     if (dev->model_name) {
1459         os_free(dev->model_name);
1460     }
1461     if (dev->model_number) {
1462         os_free(dev->model_number);
1463     }
1464     if (dev->device_name) {
1465         os_free(dev->device_name);
1466     }
1467     if (dev->serial_number) {
1468         os_free(dev->serial_number);
1469     }
1470 
1471     if (s_factory_info) {
1472         os_free(s_factory_info);
1473         s_factory_info = NULL;
1474     }
1475 
1476     return ret;
1477 }
1478 
1479 void
wifi_station_wps_timeout_internal(void)1480 wifi_station_wps_timeout_internal(void)
1481 {
1482     struct wps_sm *sm = gWpsSm;
1483 
1484     if (!sm) {
1485         return;
1486     }
1487 
1488     esp_wifi_disarm_sta_connection_timer_internal();
1489 
1490     wps_set_status(WPS_STATUS_DISABLE);
1491 
1492     esp_event_send_internal(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_TIMEOUT, 0, 0, portMAX_DELAY);
1493 }
1494 
wifi_station_wps_timeout(void)1495 void wifi_station_wps_timeout(void)
1496 {
1497 #ifdef USE_WPS_TASK
1498     wps_post(SIG_WPS_TIMER_TIMEOUT, 0);
1499     return;
1500 #else
1501     wifi_station_wps_timeout_internal();
1502 #endif
1503 }
1504 
1505 void
wifi_station_wps_msg_timeout_internal(void)1506 wifi_station_wps_msg_timeout_internal(void)
1507 {
1508     struct wps_sm *sm = gWpsSm;
1509     if (!sm) {
1510         return;
1511     }
1512 
1513     if (sm->wps->state == WPS_FINISHED) {
1514         wpa_printf(MSG_DEBUG, "wps msg timeout WPS_FINISHED");
1515         wps_finish();
1516         return;
1517     } else if (sm->wps->state == RECV_M2) {
1518         wpa_printf(MSG_DEBUG, "wps msg timeout RECV_M2");
1519         wpa_printf(MSG_DEBUG, "wps recev m2/m2d timeout------>");
1520         if (!sm->wps_pin_war) {
1521             wps_stop_process(WPS_FAIL_REASON_RECV_M2D);
1522         }
1523     }
1524     if (sm->wps_pin_war) {
1525         esp_wifi_disconnect();
1526         wps_add_discard_ap(sm->config.bssid);
1527         sm->wps_pin_war = false;
1528         os_bzero(sm->ssid, sizeof(sm->ssid));
1529         os_bzero(sm->ssid_len, sizeof(sm->ssid_len));
1530         sm->discover_ssid_cnt = 0;
1531         wifi_wps_scan();
1532     }
1533 }
1534 
wifi_station_wps_msg_timeout(void)1535 void wifi_station_wps_msg_timeout(void)
1536 {
1537 #ifdef USE_WPS_TASK
1538     wps_post(SIG_WPS_TIMER_MSG_TIMEOUT, 0);
1539     return;
1540 #else
1541     wifi_station_wps_msg_timeout_internal();
1542 #endif
1543 }
1544 
wifi_station_wps_success_internal(void)1545 void wifi_station_wps_success_internal(void)
1546 {
1547     wifi_event_sta_wps_er_success_t evt = {0};
1548     struct wps_sm *sm = gWpsSm;
1549     int i;
1550 
1551     /*
1552      * For only one AP credential don't sned event data, wps_finish() has already set
1553      * the config. This is for backward compatibility.
1554      */
1555     if (sm->ap_cred_cnt > 1) {
1556         evt.ap_cred_cnt = sm->ap_cred_cnt;
1557         for (i = 0; i < MAX_WPS_AP_CRED; i++) {
1558             os_memcpy(evt.ap_cred[i].ssid, sm->ssid[i], sm->ssid_len[i]);
1559             os_memcpy(evt.ap_cred[i].passphrase, sm->key[i], sm->key_len[i]);
1560         }
1561         esp_event_send_internal(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_SUCCESS, &evt,
1562                                 sizeof(evt), portMAX_DELAY);
1563     } else {
1564         esp_event_send_internal(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_SUCCESS,
1565                                 0, 0, portMAX_DELAY);
1566     }
1567 }
1568 
wifi_station_wps_success(void)1569 void wifi_station_wps_success(void)
1570 {
1571 #ifdef USE_WPS_TASK
1572     wps_post(SIG_WPS_TIMER_SUCCESS_CB, 0);
1573     return;
1574 #else
1575     wifi_station_wps_success_internal();
1576 #endif
1577 }
1578 
wifi_station_wps_eapol_start_handle_internal(void)1579 void wifi_station_wps_eapol_start_handle_internal(void)
1580 {
1581     wpa_printf(MSG_DEBUG, "Resend EAPOL-Start.");
1582     wps_tx_start();
1583 }
1584 
wifi_station_wps_eapol_start_handle(void)1585 void wifi_station_wps_eapol_start_handle(void)
1586 {
1587 #ifdef USE_WPS_TASK
1588     wps_post(SIG_WPS_TIMER_EAPOL_START, 0);
1589     return;
1590 #else
1591     wifi_station_wps_eapol_start_handle_internal();
1592 #endif
1593 }
1594 
1595 int
wifi_station_wps_init(void)1596 wifi_station_wps_init(void)
1597 {
1598     struct wps_funcs *wps_cb;
1599     struct wps_sm *sm = NULL;
1600     uint8_t mac[6];
1601 
1602     if (gWpsSm) {
1603         goto _out;
1604     }
1605 
1606     wpa_printf(MSG_DEBUG, "wifi sta wps init");
1607 
1608     gWpsSm = (struct wps_sm *)os_zalloc(sizeof(struct wps_sm));   /* alloc Wps_sm */
1609     if (!gWpsSm) {
1610         goto _out;
1611     }
1612 
1613     sm = gWpsSm;
1614     os_memset(sm, 0x00, sizeof(struct wps_sm));
1615 
1616     esp_wifi_get_macaddr_internal(WIFI_IF_STA, mac);
1617     os_memcpy(sm->ownaddr, mac, ETH_ALEN);
1618 
1619     sm->discover_ssid_cnt = 0;
1620     sm->ignore_sel_reg = false;
1621     sm->discard_ap_cnt = 0;
1622     os_memset(&sm->dis_ap_list, 0, WPS_MAX_DIS_AP_NUM * sizeof(struct discard_ap_list_t));
1623     os_memset(&sm->config, 0x00, sizeof(wifi_sta_config_t));
1624     sm->eapol_version = 0x1;
1625     sm->identity_len = 29;
1626     os_memcpy(sm->identity, WPS_EAP_EXT_VENDOR_TYPE, sm->identity_len);
1627     sm->wps_pin_war = false;
1628 
1629     sm->is_wps_scan = false;
1630 
1631     sm->wps_ctx = (struct wps_context *)os_zalloc(sizeof(struct wps_context)); /* alloc wps_ctx */
1632     if (!sm->wps_ctx) {
1633         goto _err;
1634     }
1635 
1636     if (wps_dev_init() != 0) {
1637         goto _err;
1638     }
1639 
1640     if ((sm->wps = wps_init()) == NULL) {         /* alloc wps_data */
1641         goto _err;
1642     }
1643 
1644     /**************80211 reference***************/
1645 
1646     if (esp_wifi_get_appie_internal(WIFI_APPIE_WPS_PR) == NULL) {            /* alloc probe req wps ie */
1647         wps_build_ic_appie_wps_pr();
1648     }
1649 
1650     if (esp_wifi_get_appie_internal(WIFI_APPIE_WPS_AR) == NULL) {           /* alloc assoc req wps ie */
1651         wps_build_ic_appie_wps_ar();
1652     }
1653 
1654     ets_timer_disarm(&sm->wps_timeout_timer);
1655     ets_timer_setfn(&sm->wps_timeout_timer, (ETSTimerFunc *)wifi_station_wps_timeout, NULL);
1656     ets_timer_disarm(&sm->wps_msg_timeout_timer);
1657     ets_timer_setfn(&sm->wps_msg_timeout_timer, (ETSTimerFunc *)wifi_station_wps_msg_timeout, NULL);
1658     ets_timer_disarm(&sm->wps_success_cb_timer);
1659     ets_timer_setfn(&sm->wps_success_cb_timer, (ETSTimerFunc *)wifi_station_wps_success, NULL);
1660     ets_timer_disarm(&sm->wps_scan_timer);
1661     ets_timer_setfn(&sm->wps_scan_timer, (ETSTimerFunc *)wifi_wps_scan, NULL);
1662     ets_timer_disarm(&sm->wps_eapol_start_timer);
1663     ets_timer_setfn(&sm->wps_eapol_start_timer, (ETSTimerFunc *)wifi_station_wps_eapol_start_handle, NULL);
1664 
1665     sm->scan_cnt = 0;
1666 
1667     wps_cb = os_malloc(sizeof(struct wps_funcs));
1668     if (wps_cb == NULL) {
1669         goto _err;
1670     } else {
1671         wps_cb->wps_parse_scan_result = wps_parse_scan_result;
1672         wps_cb->wifi_station_wps_start = wifi_station_wps_start;
1673         wps_cb->wps_sm_rx_eapol = wps_sm_rx_eapol;
1674         wps_cb->wps_start_pending = wps_start_pending;
1675         esp_wifi_set_wps_cb_internal(wps_cb);
1676     }
1677 
1678     return ESP_OK;
1679 
1680 _err:
1681     esp_wifi_unset_appie_internal(WIFI_APPIE_WPS_PR);
1682     esp_wifi_unset_appie_internal(WIFI_APPIE_WPS_AR);
1683 
1684     if (sm->dev) {
1685         wps_dev_deinit(sm->dev);
1686         sm->dev = NULL;
1687     }
1688     if (sm->wps_ctx) {
1689         os_free(sm->wps_ctx);
1690         sm->wps_ctx = NULL;
1691     }
1692     if (sm->wps) {
1693         wps_deinit();
1694         sm->wps = NULL;
1695     }
1696     os_free(gWpsSm);
1697     gWpsSm = NULL;
1698     return ESP_FAIL;
1699 _out:
1700     return ESP_FAIL;
1701 }
1702 
wps_delete_timer(void)1703 int wps_delete_timer(void)
1704 {
1705     struct wps_sm *sm = gWpsSm;
1706 
1707     if (!sm) {
1708         return ESP_OK;
1709     }
1710 
1711     ets_timer_disarm(&sm->wps_success_cb_timer);
1712     ets_timer_disarm(&sm->wps_timeout_timer);
1713     ets_timer_disarm(&sm->wps_msg_timeout_timer);
1714     ets_timer_disarm(&sm->wps_scan_timer);
1715     ets_timer_disarm(&sm->wps_eapol_start_timer);
1716     ets_timer_done(&sm->wps_success_cb_timer);
1717     ets_timer_done(&sm->wps_timeout_timer);
1718     ets_timer_done(&sm->wps_msg_timeout_timer);
1719     ets_timer_done(&sm->wps_scan_timer);
1720     ets_timer_done(&sm->wps_eapol_start_timer);
1721     esp_wifi_disarm_sta_connection_timer_internal();
1722     return ESP_OK;
1723 }
1724 
1725 int
wifi_station_wps_deinit(void)1726 wifi_station_wps_deinit(void)
1727 {
1728     struct wps_sm *sm = gWpsSm;
1729 
1730     if (gWpsSm == NULL) {
1731         return ESP_FAIL;
1732     }
1733 
1734     esp_wifi_unset_appie_internal(WIFI_APPIE_WPS_PR);
1735     esp_wifi_unset_appie_internal(WIFI_APPIE_WPS_AR);
1736     esp_wifi_set_wps_cb_internal(NULL);
1737 
1738     if (sm->dev) {
1739         wps_dev_deinit(sm->dev);
1740         sm->dev = NULL;
1741     }
1742     if (sm->wps_ctx) {
1743         os_free(sm->wps_ctx);
1744         sm->wps_ctx = NULL;
1745     }
1746     if (sm->wps) {
1747         wps_deinit();
1748         sm->wps = NULL;
1749     }
1750     os_free(gWpsSm);
1751     gWpsSm = NULL;
1752 
1753     return ESP_OK;
1754 }
1755 
1756 int
wps_station_wps_register_cb(wps_st_cb_t cb)1757 wps_station_wps_register_cb(wps_st_cb_t cb)
1758 {
1759     if (!gWpsSm) {
1760         return ESP_FAIL;
1761     }
1762 
1763     gWpsSm->st_cb = cb;
1764     return ESP_OK;
1765 }
1766 
1767 struct wps_sm *
wps_sm_get(void)1768 wps_sm_get(void)
1769 {
1770     return gWpsSm;
1771 }
1772 
1773 int
wps_ssid_save(u8 * ssid,u8 ssid_len,u8 idx)1774 wps_ssid_save(u8 *ssid, u8 ssid_len, u8 idx)
1775 {
1776     u8 *tmpssid;
1777 
1778     if (!ssid || !gWpsSm || idx > 2) {
1779         return ESP_FAIL;
1780     }
1781 
1782     os_memset(gWpsSm->ssid[idx], 0x00, sizeof(gWpsSm->ssid[idx]));
1783     os_memcpy(gWpsSm->ssid[idx], ssid, ssid_len);
1784     gWpsSm->ssid_len[idx] = ssid_len;
1785     gWpsSm->ap_cred_cnt++;
1786 
1787     tmpssid = (u8 *)os_zalloc(ssid_len + 1);
1788     if (tmpssid) {
1789         os_memcpy(tmpssid, ssid, ssid_len);
1790         wpa_printf(MSG_DEBUG, "WPS: key[%s]", tmpssid);
1791         os_free(tmpssid);
1792     }
1793     return ESP_OK;
1794 }
1795 
1796 int
wps_key_save(char * key,u8 key_len,u8 idx)1797 wps_key_save(char *key, u8 key_len, u8 idx)
1798 {
1799     u8 *tmpkey;
1800 
1801     if (!key || !gWpsSm || idx > 2) {
1802         return ESP_FAIL;
1803     }
1804 
1805     os_memset(gWpsSm->key[idx], 0x00, sizeof(gWpsSm->key[idx]));
1806     os_memcpy(gWpsSm->key[idx], key, key_len);
1807     gWpsSm->key_len[idx] = key_len;
1808 
1809     tmpkey = (u8 *)os_zalloc(key_len + 1);
1810     if (tmpkey) {
1811         os_memcpy(tmpkey, key, key_len);
1812         wpa_printf(MSG_DEBUG, "WPS: key[%s], idx - %d", tmpkey, idx);
1813         os_free(tmpkey);
1814     }
1815     return ESP_OK;
1816 }
1817 
1818 void
wifi_wps_scan_done(void * arg,STATUS status)1819 wifi_wps_scan_done(void *arg, STATUS status)
1820 {
1821     struct wps_sm *sm = gWpsSm;
1822     wifi_config_t wifi_config;
1823 
1824     wpa_printf(MSG_INFO, "WPS: scan done");
1825     if (wps_get_type() == WPS_TYPE_DISABLE) {
1826         return;
1827     }
1828 
1829     if (!sm) {
1830         return;
1831     }
1832 
1833     if (sm->discover_ssid_cnt == 1) {
1834         wps_set_status(WPS_STATUS_PENDING);
1835     } else if (sm->discover_ssid_cnt == 0)  {
1836         wps_set_status(WPS_STATUS_SCANNING);
1837     } else {
1838         wpa_printf(MSG_INFO, "PBC session overlap!");
1839         wps_set_status(WPS_STATUS_DISABLE);
1840         esp_event_send_internal(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP, 0, 0, portMAX_DELAY);
1841     }
1842 
1843     wpa_printf(MSG_DEBUG, "wps scan_done discover_ssid_cnt = %d", sm->discover_ssid_cnt);
1844 
1845     sm->discover_ssid_cnt = 0;
1846 
1847     if (wps_get_status() == WPS_STATUS_PENDING) {
1848         esp_wifi_disconnect();
1849 
1850         os_memcpy(&wifi_config.sta, &sm->config, sizeof(wifi_sta_config_t));
1851         esp_wifi_set_config(0, &wifi_config);
1852 
1853         wpa_printf(MSG_DEBUG, "WPS: neg start");
1854         esp_wifi_connect();
1855         ets_timer_disarm(&sm->wps_msg_timeout_timer);
1856         ets_timer_arm(&sm->wps_msg_timeout_timer, 2000, 0);
1857     } else if (wps_get_status() == WPS_STATUS_SCANNING) {
1858         if (wps_get_type() == WPS_TYPE_PIN && sm->scan_cnt > WPS_IGNORE_SEL_REG_MAX_CNT) {
1859             sm->ignore_sel_reg = true;
1860             sm->wps_pin_war = false;
1861         }
1862         ets_timer_arm(&sm->wps_scan_timer, 100, 0);
1863     } else {
1864         return;
1865     }
1866 }
1867 
1868 void
wifi_wps_scan_internal(void)1869 wifi_wps_scan_internal(void)
1870 {
1871     struct wps_sm *sm = gWpsSm;
1872 
1873     sm->scan_cnt++;
1874     wpa_printf(MSG_DEBUG, "wifi_wps_scan : %d", sm->scan_cnt);
1875 
1876     typedef void (* scan_done_cb_t)(void *arg, STATUS status);
1877     extern int esp_wifi_promiscuous_scan_start(wifi_scan_config_t *config, scan_done_cb_t cb);
1878     esp_wifi_promiscuous_scan_start(NULL, wifi_wps_scan_done);
1879 }
1880 
wifi_wps_scan(void)1881 void wifi_wps_scan(void)
1882 {
1883 #ifdef USE_WPS_TASK
1884     wps_post(SIG_WPS_TIMER_SCAN, 0);
1885     return;
1886 #else
1887     wifi_wps_scan_internal();
1888 #endif
1889 }
1890 
wifi_station_wps_start(void)1891 int wifi_station_wps_start(void)
1892 {
1893     struct wps_sm *sm = wps_sm_get();
1894 
1895     if (!sm) {
1896         wpa_printf(MSG_ERROR, "WPS: wps not initial");
1897         return ESP_FAIL;
1898     }
1899 
1900     ets_timer_arm(&sm->wps_timeout_timer, 120000, 0); /* 120s total */
1901 
1902     switch (wps_get_status()) {
1903     case WPS_STATUS_DISABLE: {
1904         sm->is_wps_scan = true;
1905 
1906         wps_build_public_key(sm->wps, NULL, WPS_CALC_KEY_PRE_CALC);
1907 
1908         wifi_wps_scan();
1909 
1910 
1911         break;
1912     }
1913     case WPS_STATUS_SCANNING:
1914         sm->scan_cnt = 0;
1915         ets_timer_disarm(&sm->wps_timeout_timer);
1916         ets_timer_arm(&sm->wps_timeout_timer, 120000, 0); /* 120s total */
1917         break;
1918     default:
1919         break;
1920     }
1921     sm->discard_ap_cnt = 0;
1922     os_memset(&sm->dis_ap_list, 0, WPS_MAX_DIS_AP_NUM * sizeof(struct discard_ap_list_t));
1923     esp_wifi_set_wps_start_flag_internal(true);
1924     return ESP_OK;
1925 }
1926 
wps_task_deinit(void)1927 int wps_task_deinit(void)
1928 {
1929     wpa_printf(MSG_DEBUG, "wps task deinit");
1930 
1931     if (s_wps_api_sem) {
1932         vSemaphoreDelete(s_wps_api_sem);
1933         s_wps_api_sem = NULL;
1934         wpa_printf(MSG_DEBUG, "wps task deinit: free api sem");
1935     }
1936 
1937     if (s_wps_task_create_sem) {
1938         vSemaphoreDelete(s_wps_task_create_sem);
1939         s_wps_task_create_sem = NULL;
1940         wpa_printf(MSG_DEBUG, "wps task deinit: free task create sem");
1941     }
1942 
1943     if (s_wps_queue) {
1944         vQueueDelete(s_wps_queue);
1945         s_wps_queue = NULL;
1946         wpa_printf(MSG_DEBUG, "wps task deinit: free queue");
1947     }
1948 
1949     if (STAILQ_FIRST(&s_wps_rxq) != NULL){
1950         wps_rxq_deinit();
1951     }
1952 
1953     if (s_wps_data_lock) {
1954         vSemaphoreDelete(s_wps_data_lock);
1955         s_wps_data_lock = NULL;
1956         wpa_printf(MSG_DEBUG, "wps task deinit: free data lock");
1957     }
1958 
1959     return ESP_OK;
1960 }
1961 
wps_task_init(void)1962 int wps_task_init(void)
1963 {
1964     int ret = 0;
1965 
1966     /* Call wps_task_deinit() first in case esp_wifi_wps_disable() fails
1967      */
1968     wps_task_deinit();
1969 
1970     s_wps_data_lock = xSemaphoreCreateRecursiveMutex();
1971     if (!s_wps_data_lock) {
1972         wpa_printf(MSG_ERROR, "wps task init: failed to alloc data lock");
1973         goto _wps_no_mem;
1974     }
1975 
1976     s_wps_api_sem = xSemaphoreCreateCounting(1, 0);
1977     if (!s_wps_api_sem) {
1978         wpa_printf(MSG_ERROR, "wps task init: failed to create api sem");
1979         goto _wps_no_mem;
1980     }
1981 
1982     s_wps_task_create_sem = xSemaphoreCreateCounting(1, 0);
1983     if (!s_wps_task_create_sem) {
1984         wpa_printf(MSG_ERROR, "wps task init: failed to create task sem");
1985         goto _wps_no_mem;
1986     }
1987 
1988     os_bzero(s_wps_sig_cnt, SIG_WPS_NUM);
1989     s_wps_queue = xQueueCreate(SIG_WPS_NUM, sizeof(s_wps_queue));
1990     if (!s_wps_queue) {
1991         wpa_printf(MSG_ERROR, "wps task init: failed to alloc queue");
1992         goto _wps_no_mem;
1993     }
1994 
1995     wps_rxq_init();
1996 
1997     ret = xTaskCreate(wps_task, "wpsT", WPS_TASK_STACK_SIZE, NULL, 2, &s_wps_task_hdl);
1998     if (pdPASS != ret) {
1999         wpa_printf(MSG_ERROR, "wps enable: failed to create task");
2000         goto _wps_no_mem;
2001     }
2002 
2003     xSemaphoreTake(s_wps_task_create_sem, portMAX_DELAY);
2004     vSemaphoreDelete(s_wps_task_create_sem);
2005     s_wps_task_create_sem = NULL;
2006 
2007     wpa_printf(MSG_DEBUG, "wifi wps enable: task prio:%d, stack:%d", 2, WPS_TASK_STACK_SIZE);
2008     return ESP_OK;
2009 
2010 _wps_no_mem:
2011     wps_task_deinit();
2012     return ESP_ERR_NO_MEM;
2013 }
2014 
wps_post_block(uint32_t sig,void * arg)2015 int wps_post_block(uint32_t sig, void *arg)
2016 {
2017     wps_ioctl_param_t param;
2018 
2019     param.ret = ESP_FAIL;
2020     param.arg = arg;
2021 
2022     if (ESP_OK != wps_post(sig, (uint32_t)&param)) {
2023         return ESP_FAIL;
2024     }
2025 
2026     if (pdPASS == xSemaphoreTake(s_wps_api_sem, portMAX_DELAY)) {
2027         return param.ret;
2028     } else {
2029         return ESP_FAIL;
2030     }
2031 }
2032 
wps_check_wifi_mode(void)2033 int wps_check_wifi_mode(void)
2034 {
2035     bool sniffer = false;
2036     wifi_mode_t mode;
2037     int ret;
2038 
2039     ret = esp_wifi_get_mode(&mode);
2040     if (ESP_OK != ret) {
2041         wpa_printf(MSG_ERROR, "wps check wifi mode: failed to get wifi mode ret=%d", ret);
2042         return ESP_FAIL;
2043     }
2044 
2045     ret = esp_wifi_get_promiscuous(&sniffer);
2046     if (ESP_OK != ret) {
2047         wpa_printf(MSG_ERROR, "wps check wifi mode: failed to get sniffer mode ret=%d", ret);
2048         return ESP_FAIL;
2049     }
2050 
2051     if (
2052 #ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
2053         mode == WIFI_MODE_AP ||
2054 #endif
2055         mode == WIFI_MODE_NULL || sniffer == true) {
2056         wpa_printf(MSG_ERROR, "wps check wifi mode: wrong wifi mode=%d sniffer=%d", mode, sniffer);
2057         return ESP_ERR_WIFI_MODE;
2058     }
2059 
2060     return ESP_OK;
2061 }
2062 
esp_wifi_wps_enable(const esp_wps_config_t * config)2063 int esp_wifi_wps_enable(const esp_wps_config_t *config)
2064 {
2065     int ret;
2066 
2067     if (ESP_OK != wps_check_wifi_mode()) {
2068         return ESP_ERR_WIFI_MODE;
2069     }
2070 
2071     API_MUTEX_TAKE();
2072     if (s_wps_enabled) {
2073         API_MUTEX_GIVE();
2074         wpa_printf(MSG_DEBUG, "wps enable: already enabled");
2075         return ESP_OK;
2076     }
2077 
2078 #ifdef USE_WPS_TASK
2079     ret = wps_task_init();
2080     if (ESP_OK != ret) {
2081         API_MUTEX_GIVE();
2082         return ret;
2083     }
2084 
2085     ret = wps_post_block(SIG_WPS_ENABLE, (esp_wps_config_t *)config);
2086     if (ESP_OK != ret) {
2087         wps_task_deinit();
2088         API_MUTEX_GIVE();
2089         return ret;
2090     }
2091 
2092     s_wps_enabled = true;
2093     wpa_printf(MSG_DEBUG, "wifi wps task: prio:%d, stack:%d\n", 2, WPS_TASK_STACK_SIZE);
2094     API_MUTEX_GIVE();
2095     return ret;
2096 #else
2097     ret = wifi_wps_enable_internal(config);
2098     API_MUTEX_GIVE();
2099     return ret;
2100 #endif
2101 }
2102 
wifi_wps_enable_internal(const esp_wps_config_t * config)2103 int wifi_wps_enable_internal(const esp_wps_config_t *config)
2104 {
2105     int ret = 0;
2106 
2107     wpa_printf(MSG_DEBUG, "ESP WPS crypto initialize!");
2108     if (config->wps_type == WPS_TYPE_DISABLE) {
2109         wpa_printf(MSG_ERROR, "wps enable: invalid wps type");
2110         return ESP_ERR_WIFI_WPS_TYPE;
2111     }
2112 
2113     /* currently , we don't support REGISTRAR */
2114     if (IS_WPS_REGISTRAR(config->wps_type)) {
2115         wpa_printf(MSG_ERROR, "wps enable: not support registrar");
2116         return ESP_ERR_WIFI_WPS_TYPE;
2117     }
2118 
2119     wpa_printf(MSG_DEBUG, "Set factory information.");
2120     ret = wps_set_factory_info(config);
2121     if (ret != 0) {
2122         return ret;
2123     }
2124 
2125     wpa_printf(MSG_INFO, "wifi_wps_enable\n");
2126 
2127     wps_set_type(config->wps_type);
2128     wps_set_status(WPS_STATUS_DISABLE);
2129 
2130     ret = wifi_station_wps_init();
2131 
2132     if (ret != 0) {
2133         wps_set_type(WPS_STATUS_DISABLE);
2134         wps_set_status(WPS_STATUS_DISABLE);
2135         return ESP_FAIL;
2136     }
2137 
2138     return ESP_OK;
2139 }
2140 
wifi_wps_disable_internal(void)2141 int wifi_wps_disable_internal(void)
2142 {
2143     wps_set_status(WPS_STATUS_DISABLE);
2144     wifi_station_wps_deinit();
2145     return ESP_OK;
2146 }
2147 
esp_wifi_wps_disable(void)2148 int esp_wifi_wps_disable(void)
2149 {
2150     int ret = 0;
2151 
2152     if (ESP_OK != wps_check_wifi_mode()) {
2153         return ESP_ERR_WIFI_MODE;
2154     }
2155 
2156     API_MUTEX_TAKE();
2157 
2158     if (!s_wps_enabled) {
2159         wpa_printf(MSG_DEBUG, "wps disable: already disabled");
2160         API_MUTEX_GIVE();
2161         return ESP_OK;
2162     }
2163 
2164     wpa_printf(MSG_INFO, "wifi_wps_disable\n");
2165     wps_set_type(WPS_TYPE_DISABLE); /* Notify WiFi task */
2166 
2167     /* Call wps_delete_timer to delete all WPS timer, no timer will call wps_post()
2168      * to post message to wps_task once this function returns.
2169      */
2170     wps_delete_timer();
2171 
2172 #ifdef USE_WPS_TASK
2173     ret = wps_post_block(SIG_WPS_DISABLE, 0);
2174 #else
2175     ret = wifi_wps_disable_internal();
2176 #endif
2177 
2178     if (ESP_OK != ret) {
2179         wpa_printf(MSG_ERROR, "wps disable: failed to disable wps, ret=%d", ret);
2180     }
2181 
2182     esp_wifi_disconnect();
2183     esp_wifi_set_wps_start_flag_internal(false);
2184     wps_task_deinit();
2185     s_wps_enabled = false;
2186     API_MUTEX_GIVE();
2187     return ESP_OK;
2188 }
2189 
esp_wifi_wps_start(int timeout_ms)2190 int esp_wifi_wps_start(int timeout_ms)
2191 {
2192     if (ESP_OK != wps_check_wifi_mode()) {
2193         return ESP_ERR_WIFI_MODE;
2194     }
2195 
2196     API_MUTEX_TAKE();
2197 
2198     if (!s_wps_enabled) {
2199         wpa_printf(MSG_ERROR, "wps start: wps not enabled");
2200         API_MUTEX_GIVE();
2201         return ESP_ERR_WIFI_WPS_SM;
2202     }
2203 
2204     if (wps_get_type() == WPS_TYPE_DISABLE || (wps_get_status() != WPS_STATUS_DISABLE && wps_get_status() != WPS_STATUS_SCANNING)) {
2205         API_MUTEX_GIVE();
2206         return ESP_ERR_WIFI_WPS_TYPE;
2207     }
2208 
2209     if (esp_wifi_get_user_init_flag_internal() == 0) {
2210         API_MUTEX_GIVE();
2211         return ESP_ERR_WIFI_STATE;
2212     }
2213 
2214     wpa_printf(MSG_DEBUG, "wps scan");
2215 
2216 #ifdef USE_WPS_TASK
2217     wps_post_block(SIG_WPS_START, 0);
2218 #else
2219     ic_pp_post(SIG_PP_WPS, 0);
2220 #endif
2221 
2222     API_MUTEX_GIVE();
2223     return ESP_OK;
2224 }
2225 
2226 bool
wifi_set_wps_cb(wps_st_cb_t cb)2227 wifi_set_wps_cb(wps_st_cb_t cb)
2228 {
2229     wifi_mode_t mode;
2230 
2231     esp_wifi_get_mode(&mode);
2232     if (
2233 #ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
2234         mode == WIFI_MODE_AP ||
2235 #endif
2236         mode == WIFI_MODE_NULL) {
2237         return false;
2238     }
2239 
2240     if (wps_station_wps_register_cb(cb) == 0) {
2241         return true;
2242     }
2243 
2244     return false;
2245 }
2246