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 "esp_err.h"
10 
11 #include "utils/includes.h"
12 #include "utils/common.h"
13 #include "utils/wpa_debug.h"
14 #include "common/wpa_ctrl.h"
15 #include "common/eapol_common.h"
16 #include "common/ieee802_11_defs.h"
17 #include "utils/state_machine.h"
18 #include "rsn_supp/wpa.h"
19 
20 #include "crypto/crypto.h"
21 
22 #include "utils/ext_password.h"
23 #include "tls/tls.h"
24 #include "eap_peer/eap_i.h"
25 #include "eap_peer/eap_config.h"
26 #include "eap_peer/eap.h"
27 #include "eap_peer/eap_tls.h"
28 #ifdef EAP_PEER_METHOD
29 #include "eap_peer/eap_methods.h"
30 #endif
31 
32 #include "esp_wifi_driver.h"
33 #include "esp_private/wifi.h"
34 #include "esp_wpa_err.h"
35 
36 #define WPA2_VERSION    "v2.0"
37 
38 #define DATA_MUTEX_TAKE() k_sem_take(&s_wpa2_data_lock,K_FOREVER)
39 #define DATA_MUTEX_GIVE() k_sem_give(&s_wpa2_data_lock)
40 
41 //length of the string "fast_provisioning={0/1/2} "
42 #define FAST_PROVISIONING_CONFIG_STR_LEN 20
43 //length of the string "fast_max_pac_list_len=(int < 100) "
44 #define FAST_MAX_PAC_LIST_CONFIG_STR_LEN 25
45 //length of the string "fast_pac_format=binary"
46 #define FAST_PAC_FORMAT_STR_LEN 22
47 //Total
48 #define PHASE1_PARAM_STRING_LEN FAST_PROVISIONING_CONFIG_STR_LEN + FAST_MAX_PAC_LIST_CONFIG_STR_LEN + FAST_PAC_FORMAT_STR_LEN
49 
50 static struct k_sem s_wpa2_data_lock;
51 
52 static struct eap_sm *gEapSm = NULL;
53 
54 static int eap_peer_sm_init(void);
55 static void eap_peer_sm_deinit(void);
56 
57 static int eap_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len, uint8_t *bssid);
58 static int wpa2_start_eapol_internal(void);
59 int wpa2_post(uint32_t sig, uint32_t par);
60 
61 #ifdef USE_WPA2_TASK
62 void wpa2_task(void *pvParameters );
63 K_THREAD_DEFINE(s_wpa2_task_hdl, WPA2_TASK_STACK_SIZE, wpa2_task, NULL, NULL, NULL,	2, 0, 0);
64 K_MSGQ_DEFINE(s_wpa2_queue, sizeof(ETSEvent), SIG_WPA2_MAX, 4);
65 static wpa2_state_t s_wpa2_state = WPA2_STATE_DISABLED;
66 K_SEM_DEFINE(s_wpa2_api_lock, 0, 20);
67 K_SEM_DEFINE(s_wifi_wpa2_sync_sem, 0, 1);
68 static bool s_disable_time_check = true;
69 
wpa2_api_lock(void)70 static void wpa2_api_lock(void)
71 {
72 	k_sem_take(&s_wpa2_api_lock, K_FOREVER);
73 }
74 
wpa2_api_unlock(void)75 static void wpa2_api_unlock(void)
76 {
77 	k_sem_give(&s_wpa2_api_lock);
78 }
79 
wpa2_is_enabled(void)80 static bool inline wpa2_is_enabled(void)
81 {
82     return (s_wpa2_state == WPA2_STATE_ENABLED);
83 }
84 
wpa2_is_disabled(void)85 static bool inline wpa2_is_disabled(void)
86 {
87     return (s_wpa2_state == WPA2_STATE_DISABLED);
88 }
89 
wpa2_set_state(wpa2_state_t state)90 static void inline wpa2_set_state(wpa2_state_t state)
91 {
92     s_wpa2_state = state;
93 }
94 
wpa2_set_eap_state(wpa2_ent_eap_state_t state)95 static void wpa2_set_eap_state(wpa2_ent_eap_state_t state)
96 {
97     if (!gEapSm) {
98         return;
99     }
100 
101     gEapSm->finish_state = state;
102     esp_wifi_set_wpa2_ent_state_internal(state);
103 }
104 
wpa2_task_delete(void * arg)105 static inline void wpa2_task_delete(void *arg)
106 {
107     k_tid_t my_task_hdl = k_current_get();
108     int ret = ESP_OK;
109 
110     if (my_task_hdl == s_wpa2_task_hdl) {
111         wpa_printf(MSG_ERROR, "WPA2: should never call task delete api in wpa2 task context");
112         return;
113     }
114 
115     ret = wpa2_post(SIG_WPA2_TASK_DEL, 0);
116 
117     if (ESP_OK != ret) {
118         wpa_printf(MSG_ERROR, "WPA2: failed to post task delete event, ret=%d", ret);
119         return;
120     }
121 }
122 
123 #define WPA_ADDR_LEN 6
124 struct wpa2_rx_param {
125     uint8_t *bssid;
126     u8 sa[WPA_ADDR_LEN];
127     u8 *buf;
128     int len;
129     STAILQ_ENTRY(wpa2_rx_param) bqentry;
130 };
131 static STAILQ_HEAD(, wpa2_rx_param) s_wpa2_rxq;
132 
wpa2_rxq_init(void)133 static void wpa2_rxq_init(void)
134 {
135     DATA_MUTEX_TAKE();
136     STAILQ_INIT(&s_wpa2_rxq);
137     DATA_MUTEX_GIVE();
138 }
139 
wpa2_rxq_enqueue(struct wpa2_rx_param * param)140 static void wpa2_rxq_enqueue(struct wpa2_rx_param *param)
141 {
142     DATA_MUTEX_TAKE();
143     STAILQ_INSERT_TAIL(&s_wpa2_rxq,param, bqentry);
144     DATA_MUTEX_GIVE();
145 }
146 
wpa2_rxq_dequeue(void)147 static struct wpa2_rx_param * wpa2_rxq_dequeue(void)
148 {
149     struct wpa2_rx_param *param = NULL;
150     DATA_MUTEX_TAKE();
151     if ((param = STAILQ_FIRST(&s_wpa2_rxq)) != NULL) {
152         STAILQ_REMOVE_HEAD(&s_wpa2_rxq, bqentry);
153         STAILQ_NEXT(param,bqentry) = NULL;
154     }
155     DATA_MUTEX_GIVE();
156     return param;
157 }
158 
wpa2_rxq_deinit(void)159 static void wpa2_rxq_deinit(void)
160 {
161     struct wpa2_rx_param *param = NULL;
162     DATA_MUTEX_TAKE();
163     while ((param = STAILQ_FIRST(&s_wpa2_rxq)) != NULL) {
164         STAILQ_REMOVE_HEAD(&s_wpa2_rxq, bqentry);
165         STAILQ_NEXT(param,bqentry) = NULL;
166         os_free(param->buf);
167         os_free(param);
168     }
169     DATA_MUTEX_GIVE();
170 }
171 
wpa2_task(void * pvParameters)172 void wpa2_task(void *pvParameters )
173 {
174     ETSEvent *e;
175     struct eap_sm *sm = gEapSm;
176     bool task_del = false;
177 
178     if (!sm) {
179         return;
180     }
181 
182     for (;;) {
183 		if (k_msgq_get(&s_wpa2_queue, &e, K_FOREVER) == 0) {
184             if (e->sig < SIG_WPA2_MAX) {
185                 DATA_MUTEX_TAKE();
186                 if(sm->wpa2_sig_cnt[e->sig]) {
187                     sm->wpa2_sig_cnt[e->sig]--;
188                 } else {
189                     wpa_printf(MSG_ERROR, "wpa2_task: invalid sig cnt, sig=%d cnt=%d", e->sig, sm->wpa2_sig_cnt[e->sig]);
190                 }
191                 DATA_MUTEX_GIVE();
192             }
193             switch (e->sig) {
194             case SIG_WPA2_TASK_DEL:
195                 task_del = true;
196                 break;
197             case SIG_WPA2_START:
198                 wpa2_start_eapol_internal();
199                 break;
200             case SIG_WPA2_RX: {
201                 struct wpa2_rx_param *param = NULL;
202 
203                 while ((param = wpa2_rxq_dequeue()) != NULL){
204                     eap_sm_rx_eapol_internal(param->sa, param->buf, param->len, param->bssid);
205                     os_free(param->buf);
206                     os_free(param);
207                 }
208                 break;
209             }
210             default:
211                 break;
212             }
213             os_free(e);
214         }
215 
216         if (task_del) {
217             break;
218         } else {
219             wpa_printf(MSG_DEBUG, "WPA2: wifi->wpa2 api completed sig(%d)", e->sig);
220 			k_sem_give(&s_wifi_wpa2_sync_sem);
221         }
222     }
223 
224     wpa_printf(MSG_DEBUG, "WPA2: queue deleted");
225     k_free(&s_wpa2_queue);
226     wpa_printf(MSG_DEBUG, "WPA2: task deleted");
227     wpa_printf(MSG_DEBUG, "WPA2: wifi->wpa2 api completed sig(%d)", e->sig);
228 	k_sem_give(&s_wifi_wpa2_sync_sem);
229 }
230 
wpa2_post(uint32_t sig,uint32_t par)231 int wpa2_post(uint32_t sig, uint32_t par)
232 {
233     struct eap_sm *sm = gEapSm;
234 
235     if (!sm) {
236         return ESP_FAIL;
237     }
238 
239     DATA_MUTEX_TAKE();
240     if (sm->wpa2_sig_cnt[sig]) {
241         DATA_MUTEX_GIVE();
242         return ESP_OK;
243     } else {
244         ETSEvent *evt = (ETSEvent *)os_malloc(sizeof(ETSEvent));
245         if (evt == NULL) {
246             wpa_printf(MSG_ERROR, "WPA2: E N M\n");
247             DATA_MUTEX_GIVE();
248             return ESP_FAIL;
249         }
250         sm->wpa2_sig_cnt[sig]++;
251         DATA_MUTEX_GIVE();
252         evt->sig = sig;
253         evt->par = par;
254 		if (k_msgq_put(&s_wpa2_queue, &evt, K_MSEC(10)) != 0) {
255             wpa_printf(MSG_ERROR, "WPA2: Q S E");
256             return ESP_FAIL;
257         } else {
258 			k_sem_take(&s_wifi_wpa2_sync_sem, K_FOREVER);
259             wpa_printf(MSG_DEBUG, "WPA2: wpa2 api return, sm->state(%d)", sm->finish_state);
260         }
261     }
262     return ESP_OK;
263 }
264 
265 #endif /* USE_WPA2_TASK */
266 
wpa2_sendto_wrapper(void * buffer,uint16_t len)267 static void wpa2_sendto_wrapper(void *buffer, uint16_t len)
268 {
269     esp_wifi_internal_tx(WIFI_IF_STA, buffer, len);
270 }
271 
wpa2_sm_ether_send(struct eap_sm * sm,const u8 * dest,u16 proto,const u8 * data,size_t data_len)272 static inline int wpa2_sm_ether_send(struct eap_sm *sm, const u8 *dest, u16 proto,
273                                      const u8 *data, size_t data_len)
274 {
275     void *buffer = (void *)(data - sizeof(struct l2_ethhdr));
276     struct l2_ethhdr *eth = NULL;
277 
278     if (!buffer) {
279         wpa_printf(MSG_ERROR, "wpa2: invalid data");
280         return ESP_FAIL;
281     } else {
282         eth = (struct l2_ethhdr *)buffer;
283         memcpy(eth->h_dest, dest, ETH_ALEN);
284         memcpy(eth->h_source, sm->ownaddr, ETH_ALEN);
285         eth->h_proto = host_to_be16(proto);
286         wpa2_sendto_wrapper(buffer, sizeof(struct l2_ethhdr) + data_len);
287     }
288 
289     return ESP_OK;
290 }
291 
wpa2_sm_alloc_eapol(struct eap_sm * sm,u8 type,const void * data,u16 data_len,size_t * msg_len,void ** data_pos)292 u8 *wpa2_sm_alloc_eapol(struct eap_sm *sm, u8 type,
293                         const void *data, u16 data_len,
294                         size_t *msg_len, void **data_pos)
295 {
296     void *buffer;
297     struct ieee802_1x_hdr *hdr;
298 
299     *msg_len = sizeof(struct ieee802_1x_hdr) + data_len;
300     /* XXX: reserve l2_ethhdr is enough */
301     buffer = os_malloc(*msg_len + sizeof(struct l2_ethhdr));
302 
303     if (buffer == NULL) {
304         return NULL;
305     }
306 
307     hdr = (struct ieee802_1x_hdr *)((char *)buffer + sizeof(struct l2_ethhdr));
308     hdr->version = 0x01;
309     hdr->type = type;
310     hdr->length = host_to_be16(data_len);
311 
312     if (data) {
313         memcpy(hdr + 1, data, data_len);
314     } else {
315         memset(hdr + 1, 0, data_len);
316     }
317 
318     if (data_pos) {
319         *data_pos = hdr + 1;
320     }
321 
322     return (u8 *) hdr;
323 }
324 
325 
wpa2_sm_free_eapol(u8 * buffer)326 void wpa2_sm_free_eapol(u8 *buffer)
327 {
328     if (buffer != NULL) {
329         buffer = buffer - sizeof(struct l2_ethhdr);
330         os_free(buffer);
331     }
332 
333 }
334 
eap_sm_send_eapol(struct eap_sm * sm,struct wpabuf * resp)335 int eap_sm_send_eapol(struct eap_sm *sm, struct wpabuf *resp)
336 {
337     size_t outlen;
338     int ret;
339     u8 *outbuf = NULL;
340 
341     u8 bssid[6];
342     ret = esp_wifi_get_assoc_bssid_internal(bssid);
343 
344     if (ret != 0) {
345         wpa_printf(MSG_DEBUG, "bssid is empty \n");
346         return WPA_ERR_INVALID_BSSID;
347     }
348 
349     outbuf = wpa2_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAP_PACKET,
350                                  wpabuf_head_u8(resp), wpabuf_len(resp),
351                                  &outlen, NULL);
352     if (!outbuf) {
353         return ESP_ERR_NO_MEM;
354     }
355 
356     ret = wpa2_sm_ether_send(sm, bssid, ETH_P_EAPOL, outbuf, outlen);
357     wpa2_sm_free_eapol(outbuf);
358     if (ret) {
359         return ESP_FAIL;
360     }
361 
362     return ESP_OK;
363 }
364 
eap_sm_process_request(struct eap_sm * sm,struct wpabuf * reqData)365 int eap_sm_process_request(struct eap_sm *sm, struct wpabuf *reqData)
366 {
367     size_t plen;
368     u32 reqVendor, reqVendorMethod;
369     u8 type, *pos;
370     struct eap_hdr *ehdr;
371     const struct eap_method *m = NULL;
372     struct wpabuf *resp = NULL;
373     struct eap_method_ret m_res;
374     int ret = 0;
375 
376     if (reqData == NULL || wpabuf_len(reqData) < sizeof(*ehdr)) {
377         return ESP_ERR_INVALID_ARG;
378     }
379 
380     ehdr = (struct eap_hdr *)wpabuf_head(reqData);
381     plen = be_to_host16(ehdr->length);
382     if (plen > wpabuf_len(reqData)) {
383         return ESP_FAIL;
384     }
385 
386     if (ehdr->identifier == sm->current_identifier &&
387         sm->lastRespData != NULL) {
388         /*Retransmit*/
389         resp = sm->lastRespData;
390         goto send_resp;
391     }
392 
393     sm->current_identifier = ehdr->identifier;
394 
395     pos = (u8 *)(ehdr + 1);
396     type = *pos++;
397     if (type == EAP_TYPE_IDENTITY) {
398         resp = (struct wpabuf *)eap_sm_build_identity_resp(sm, ehdr->identifier, 0);
399         goto send_resp;
400     } else if (type == EAP_TYPE_NOTIFICATION) {
401         /*Ignore*/
402         goto out;
403     } else if (type == EAP_TYPE_EXPANDED) {
404         if (plen < sizeof(*ehdr) + 8) {
405             return ESP_FAIL;
406         }
407         reqVendor = WPA_GET_BE24(pos);
408         pos += 3;
409         reqVendorMethod = WPA_GET_BE32(pos);
410     } else {
411         reqVendor = EAP_VENDOR_IETF;
412         reqVendorMethod = type;
413     }
414 
415     if (sm->m && sm->m->process && sm->eap_method_priv &&
416             reqVendor == sm->m->vendor &&
417             reqVendorMethod == sm->m->method) {
418         resp = sm->m->process(sm, sm->eap_method_priv,
419                               &m_res, reqData);
420     } else {
421         m = eap_peer_get_eap_method(reqVendor, reqVendorMethod);
422         if (m == NULL) {
423             goto build_nak;
424         }
425         if (sm->m) {
426             eap_deinit_prev_method(sm, "GET_METHOD");
427         }
428         sm->m = m;
429         sm->eap_method_priv = sm->m->init(sm);
430         if (sm->eap_method_priv == NULL) {
431             wpa_printf(MSG_ERROR, "Method private structure allocated failure\n");
432             sm->m = NULL;
433             goto build_nak;
434         }
435 
436         if (sm->m->process) {
437             resp = sm->m->process(sm, sm->eap_method_priv, &m_res, reqData);
438         }
439     }
440 
441     if (sm->m->isKeyAvailable && sm->m->getKey &&
442             sm->m->isKeyAvailable(sm, sm->eap_method_priv)) {
443         if (sm->eapKeyData) {
444             os_free(sm->eapKeyData);
445         }
446         sm->eapKeyData = sm->m->getKey(sm, sm->eap_method_priv,
447                                        &sm->eapKeyDataLen);
448     }
449     goto send_resp;
450 
451 build_nak:
452     resp = (struct wpabuf *)eap_sm_build_nak(sm, type, ehdr->identifier);
453     if (resp == NULL) {
454         return ESP_FAIL;
455     }
456 send_resp:
457     if (resp == NULL) {
458         wpa_printf(MSG_ERROR, "Response build fail, return.");
459         wpabuf_free(sm->lastRespData);
460         sm->lastRespData = resp;
461         wpa2_set_eap_state(WPA2_ENT_EAP_STATE_FAIL);
462         return WPA2_ENT_EAP_STATE_FAIL;
463     }
464     ret = eap_sm_send_eapol(sm, resp);
465     if (resp != sm->lastRespData) {
466         wpabuf_free(sm->lastRespData);
467     }
468     if (ret != ESP_OK) {
469         wpabuf_free(resp);
470         resp = NULL;
471         if (ret == WPA_ERR_INVALID_BSSID) {
472             ret = WPA2_ENT_EAP_STATE_FAIL;
473             wpa2_set_eap_state(WPA2_ENT_EAP_STATE_FAIL);
474         }
475     }
476     sm->lastRespData = resp;
477 out:
478     return ret;
479 }
480 
eap_sm_rx_eapol(u8 * src_addr,u8 * buf,u32 len,uint8_t * bssid)481 static int eap_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len, uint8_t *bssid)
482 {
483     struct eap_sm *sm = gEapSm;
484 
485     if (!sm) {
486         return ESP_FAIL;
487     }
488 #ifdef USE_WPA2_TASK
489     {
490         struct wpa2_rx_param *param = (struct wpa2_rx_param *)os_zalloc(sizeof(struct wpa2_rx_param));   /* free in task */
491 
492         if (!param) {
493             return ESP_ERR_NO_MEM;
494         }
495 
496         param->buf = (u8 *)os_zalloc(len);   /* free in task */
497         if (!param->buf) {
498             os_free(param);
499             return ESP_ERR_NO_MEM;
500         }
501         param->bssid = bssid;
502         memcpy(param->buf, buf, len);
503         param->len = len;
504         memcpy(param->sa, src_addr, WPA_ADDR_LEN);
505 
506         wpa2_rxq_enqueue(param);
507         return wpa2_post(SIG_WPA2_RX, 0);
508     }
509 #else
510 
511     return eap_sm_rx_eapol_internal(src_addr, buf, len, bssid);
512 #endif
513 }
514 
wpa2_ent_rx_eapol(u8 * src_addr,u8 * buf,u32 len,uint8_t * bssid)515 static int wpa2_ent_rx_eapol(u8 *src_addr, u8 *buf, u32 len, uint8_t *bssid)
516 {
517     struct ieee802_1x_hdr *hdr;
518     int ret = ESP_OK;
519 
520     hdr = (struct ieee802_1x_hdr *) buf;
521 
522     switch (hdr->type) {
523 	    case IEEE802_1X_TYPE_EAPOL_START:
524 	    case IEEE802_1X_TYPE_EAP_PACKET:
525 	    case IEEE802_1X_TYPE_EAPOL_LOGOFF:
526 		    ret = eap_sm_rx_eapol(src_addr, buf, len, bssid);
527 		    break;
528 	    case IEEE802_1X_TYPE_EAPOL_KEY:
529             ret = wpa_sm_rx_eapol(src_addr, buf, len);
530 		    break;
531 	    default:
532 		wpa_printf(MSG_ERROR, "Unknown EAPOL packet type - %d\n", hdr->type);
533 		    break;
534     }
535 
536 	return ret;
537 }
538 
eap_sm_rx_eapol_internal(u8 * src_addr,u8 * buf,u32 len,uint8_t * bssid)539 static int eap_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len, uint8_t *bssid)
540 {
541     struct eap_sm *sm = gEapSm;
542     u32 plen, data_len;
543     struct ieee802_1x_hdr *hdr;
544     struct eap_hdr *ehdr;
545     struct wpabuf *req = NULL;
546     u8 *tmp;
547     int ret = ESP_FAIL;
548 
549     if (!sm) {
550         return ESP_FAIL;
551     }
552 
553     if (len < sizeof(*hdr) + sizeof(*ehdr)) {
554 #ifdef DEBUG_PRINT
555         wpa_printf(MSG_DEBUG, "WPA: EAPOL frame too short to be a WPA "
556                    "EAPOL-Key (len %lu, expecting at least %lu)",
557                    (unsigned long) len,
558                    (unsigned long) sizeof(*hdr) + sizeof(*ehdr));
559 #endif
560         return ESP_FAIL;
561     }
562 
563     tmp = buf;
564 
565     hdr = (struct ieee802_1x_hdr *) tmp;
566     ehdr = (struct eap_hdr *) (hdr + 1);
567     plen = be_to_host16(hdr->length);
568     data_len = plen + sizeof(*hdr);
569 
570 #ifdef DEBUG_PRINT
571     wpa_printf(MSG_DEBUG, "IEEE 802.1X RX: version=%d type=%d length=%d\n",
572                hdr->version, hdr->type, plen);
573 #endif
574     if (hdr->version < EAPOL_VERSION) {
575         /* TODO: backwards compatibility */
576     }
577     if (hdr->type != IEEE802_1X_TYPE_EAP_PACKET) {
578 #ifdef DEBUG_PRINT
579         wpa_printf(MSG_DEBUG, "WPA2: EAP frame (type %u) discarded, "
580                    "not a EAP PACKET frame", hdr->type);
581 #endif
582         ret = -2;
583         goto _out;
584     }
585     if (plen > len - sizeof(*hdr) || plen < sizeof(*ehdr)) {
586 #ifdef DEBUG_PRINT
587         wpa_printf(MSG_DEBUG, "WPA2: EAPOL frame payload size %lu "
588                    "invalid (frame size %lu)",
589                    (unsigned long) plen, (unsigned long) len);
590 #endif
591         ret = -2;
592         goto _out;
593     }
594 
595     wpa_hexdump(MSG_MSGDUMP, "WPA2: RX EAPOL-EAP PACKET", tmp, len);
596 
597     if (data_len < len) {
598 #ifdef DEBUG_PRINT
599         wpa_printf(MSG_DEBUG, "WPA: ignoring %lu bytes after the IEEE "
600                    "802.1X data\n", (unsigned long) len - data_len);
601 #endif
602     }
603 
604 #ifdef EAP_PEER_METHOD
605     switch (ehdr->code) {
606     case EAP_CODE_REQUEST:
607         /* Handle EAP-reauthentication case */
608         if (sm->finish_state == WPA2_ENT_EAP_STATE_SUCCESS) {
609                 wpa_printf(MSG_INFO, ">>>>>wpa2 EAP Re-authentication in progress\n");
610 		wpa2_set_eap_state(WPA2_ENT_EAP_STATE_IN_PROGRESS);
611 	}
612 
613         req = wpabuf_alloc_copy((u8 *)ehdr, len - sizeof(*hdr));
614         ret = eap_sm_process_request(sm, req);
615         break;
616     case EAP_CODE_RESPONSE:
617         /*Ignore*/
618         break;
619     case EAP_CODE_SUCCESS:
620         if (sm->eapKeyData) {
621             wpa_set_pmk(sm->eapKeyData, NULL, false);
622             os_free(sm->eapKeyData);
623             sm->eapKeyData = NULL;
624             wpa_printf(MSG_INFO, ">>>>>wpa2 FINISH\n");
625             ret = WPA2_ENT_EAP_STATE_SUCCESS;
626             wpa2_set_eap_state(WPA2_ENT_EAP_STATE_SUCCESS);
627 	    eap_deinit_prev_method(sm, "EAP Success");
628         } else {
629             wpa_printf(MSG_INFO, ">>>>>wpa2 FAILED, receive EAP_SUCCESS but pmk is empty, potential attack!\n");
630             ret = WPA2_ENT_EAP_STATE_FAIL;
631             wpa2_set_eap_state(WPA2_ENT_EAP_STATE_FAIL);
632         }
633         break;
634     case EAP_CODE_FAILURE:
635         wpa_printf(MSG_INFO, ">>>>>wpa2 FAILED\n");
636         ret = WPA2_ENT_EAP_STATE_FAIL;
637         wpa2_set_eap_state(WPA2_ENT_EAP_STATE_FAIL);
638         break;
639     }
640 _out:
641     wpabuf_free(req);
642 #endif
643     return ret;
644 }
645 
wpa2_start_eapol(void)646 static int wpa2_start_eapol(void)
647 {
648 #ifdef USE_WPA2_TASK
649     return wpa2_post(SIG_WPA2_START, 0);
650 #else
651     return wpa2_start_eapol_internal();
652 #endif
653 }
654 
wpa2_start_eapol_internal(void)655 static int wpa2_start_eapol_internal(void)
656 {
657     struct eap_sm *sm = gEapSm;
658     int ret = 0;
659     u8 bssid[6];
660     u8 *buf;
661     size_t len;
662 
663     if (!sm) {
664         return ESP_FAIL;
665     }
666 
667     if (wpa_sta_cur_pmksa_matches_akm()) {
668         wpa_printf(MSG_DEBUG,
669                 "RSN: PMKSA caching - do not send EAPOL-Start");
670         return ESP_FAIL;
671     }
672 
673     ret = esp_wifi_get_assoc_bssid_internal(bssid);
674     if (ret != 0) {
675         wpa_printf(MSG_ERROR, "bssid is empty!");
676         return WPA_ERR_INVALID_BSSID;
677     }
678 
679     buf = wpa2_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START, (u8 *)"", 0, &len, NULL);
680     if (!buf) {
681         return ESP_FAIL;
682     }
683 
684     wpa2_set_eap_state(WPA2_ENT_EAP_STATE_IN_PROGRESS);
685     wpa2_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len);
686     wpa2_sm_free_eapol(buf);
687     return ESP_OK;
688 }
689 
690 /**
691  * eap_peer_sm_init - Allocate and initialize EAP peer state machine
692  * @eapol_ctx: Context data to be used with eapol_cb calls
693  * @eapol_cb: Pointer to EAPOL callback functions
694  * @msg_ctx: Context data for wpa_msg() calls
695  * @conf: EAP configuration
696  * Returns: Pointer to the allocated EAP state machine or %NULL on failure
697  *
698  * This function allocates and initializes an EAP state machine. In addition,
699  * this initializes TLS library for the new EAP state machine. eapol_cb pointer
700  * will be in use until eap_peer_sm_deinit() is used to deinitialize this EAP
701  * state machine. Consequently, the caller must make sure that this data
702  * structure remains alive while the EAP state machine is active.
703  */
eap_peer_sm_init(void)704 static int eap_peer_sm_init(void)
705 {
706     int ret = 0;
707     struct eap_sm *sm;
708 
709     if (gEapSm) {
710         wpa_printf(MSG_ERROR, "WPA2: wpa2 sm not null, deinit it");
711         eap_peer_sm_deinit();
712     }
713 
714     sm = (struct eap_sm *)os_zalloc(sizeof(*sm));
715     if (sm == NULL) {
716         ret = ESP_ERR_NO_MEM;
717         return ret;
718     }
719 
720     gEapSm = sm;
721 
722 	k_sem_init(&s_wpa2_data_lock, 0, 1);
723 
724     wpa2_set_eap_state(WPA2_ENT_EAP_STATE_NOT_START);
725     sm->current_identifier = 0xff;
726     esp_wifi_get_macaddr_internal(WIFI_IF_STA, sm->ownaddr);
727     ret = eap_peer_blob_init(sm);
728     if (ret) {
729         wpa_printf(MSG_ERROR, "eap_peer_blob_init failed\n");
730         ret = ESP_FAIL;
731         goto _err;
732     }
733 
734     ret = eap_peer_config_init(sm, g_wpa_private_key_passwd, g_wpa_private_key_passwd_len);
735     if (ret) {
736         wpa_printf(MSG_ERROR, "eap_peer_config_init failed\n");
737         ret = ESP_FAIL;
738         goto _err;
739     }
740 
741     sm->ssl_ctx = tls_init();
742     if (sm->ssl_ctx == NULL) {
743         wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS context.");
744         ret = ESP_FAIL;
745         goto _err;
746     }
747 
748     wpa2_rxq_init();
749 
750     gEapSm = sm;
751 #ifdef USE_WPA2_TASK
752 	k_thread_name_set(s_wpa2_task_hdl, "wpa2T");
753     wpa_printf(MSG_INFO, "wpa2_task prio:%d, stack:%d\n", 2, WPA2_TASK_STACK_SIZE);
754 #endif
755     return ESP_OK;
756 
757 _err:
758     eap_peer_sm_deinit();
759     return ret;
760 }
761 
762 /**
763  * eap_peer_sm_deinit - Deinitialize and free an EAP peer state machine
764  * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
765  *
766  * This function deinitializes EAP state machine and frees all allocated
767  * resources.
768  */
eap_peer_sm_deinit(void)769 static void eap_peer_sm_deinit(void)
770 {
771     struct eap_sm *sm = gEapSm;
772 
773     if (sm == NULL) {
774         return;
775     }
776 
777     eap_peer_config_deinit(sm);
778     eap_peer_blob_deinit(sm);
779     eap_deinit_prev_method(sm, "EAP deinit");
780     eap_sm_abort(sm);
781     tls_deinit(sm->ssl_ctx);
782 #ifdef USE_WPA2_TASK
783     wpa2_task_delete(0);
784 #endif
785 
786     if (STAILQ_FIRST((&s_wpa2_rxq)) != NULL) {
787         wpa2_rxq_deinit();
788     }
789 
790 #ifdef USE_WPA2_TASK
791     k_free(&s_wifi_wpa2_sync_sem);
792 #endif
793 
794     k_free(&s_wpa2_data_lock);
795     wpa_printf(MSG_DEBUG, "wpa2 eap_peer_sm_deinit: free data lock");
796 
797 #ifdef USE_WPA2_TASK
798     k_free(&s_wpa2_queue);
799 #endif
800 
801     os_free(sm);
802     gEapSm = NULL;
803 }
804 
esp_wifi_sta_wpa2_ent_enable_fn(void * arg)805 esp_err_t esp_wifi_sta_wpa2_ent_enable_fn(void *arg)
806 {
807     struct wpa2_funcs *wpa2_cb;
808 
809     wpa_printf(MSG_INFO, "WPA2 ENTERPRISE VERSION: [%s] enable\n",
810                WPA2_VERSION);
811 
812     wpa2_cb = (struct wpa2_funcs *)os_zalloc(sizeof(struct wpa2_funcs));
813     if (wpa2_cb == NULL) {
814         wpa_printf(MSG_ERROR, "WPA2: no mem for wpa2 cb\n");
815         return ESP_ERR_NO_MEM;
816     }
817 
818     wpa2_cb->wpa2_sm_rx_eapol = wpa2_ent_rx_eapol;
819     wpa2_cb->wpa2_start = wpa2_start_eapol;
820     wpa2_cb->wpa2_init = eap_peer_sm_init;
821     wpa2_cb->wpa2_deinit = eap_peer_sm_deinit;
822 
823     esp_wifi_register_wpa2_cb_internal(wpa2_cb);
824 
825     wpa_printf(MSG_DEBUG, "WPA2 ENTERPRISE CRYPTO INIT.\r\n");
826 
827 #ifdef EAP_PEER_METHOD
828     if (eap_peer_register_methods()) {
829         wpa_printf(MSG_ERROR, "Register EAP Peer methods Failure\n");
830     }
831 #endif
832     return ESP_OK;
833 }
834 
esp_wifi_sta_wpa2_ent_enable(void)835 esp_err_t esp_wifi_sta_wpa2_ent_enable(void)
836 {
837     wifi_wpa2_param_t param;
838     esp_err_t ret;
839 
840     wpa2_api_lock();
841 
842     if (wpa2_is_enabled()) {
843         wpa_printf(MSG_INFO, "WPA2: already enabled");
844         wpa2_api_unlock();
845         return ESP_OK;
846     }
847 
848     param.fn = (wifi_wpa2_fn_t)esp_wifi_sta_wpa2_ent_enable_fn;
849     param.param = NULL;
850 
851     ret = esp_wifi_sta_wpa2_ent_enable_internal(&param);
852 
853     if (ESP_OK == ret) {
854         wpa2_set_state(WPA2_STATE_ENABLED);
855     } else {
856         wpa_printf(MSG_ERROR, "failed to enable wpa2 ret=%d", ret);
857     }
858 
859     wpa2_api_unlock();
860 
861     return ret;
862 }
863 
esp_wifi_sta_wpa2_ent_disable_fn(void * param)864 esp_err_t esp_wifi_sta_wpa2_ent_disable_fn(void *param)
865 {
866     wpa_printf(MSG_INFO, "WPA2 ENTERPRISE VERSION: [%s] disable\n", WPA2_VERSION);
867     esp_wifi_unregister_wpa2_cb_internal();
868 
869     if (gEapSm) {
870         eap_peer_sm_deinit();
871     }
872 
873 #ifdef USE_WPA2_TASK
874 #endif
875 
876 #ifdef EAP_PEER_METHOD
877     eap_peer_unregister_methods();
878 #endif
879 
880     return ESP_OK;
881 }
882 
esp_wifi_sta_wpa2_ent_disable(void)883 esp_err_t esp_wifi_sta_wpa2_ent_disable(void)
884 {
885     wifi_wpa2_param_t param;
886     esp_err_t ret;
887 
888     wpa2_api_lock();
889 
890     if (wpa2_is_disabled()) {
891         wpa_printf(MSG_INFO, "WPA2: already disabled");
892         wpa2_api_unlock();
893         return ESP_OK;
894     }
895 
896     param.fn = (wifi_wpa2_fn_t)esp_wifi_sta_wpa2_ent_disable_fn;
897     param.param = 0;
898     ret = esp_wifi_sta_wpa2_ent_disable_internal(&param);
899 
900     if (ESP_OK == ret) {
901         wpa2_set_state(WPA2_STATE_DISABLED);
902     } else {
903         wpa_printf(MSG_ERROR, "failed to disable wpa2 ret=%d", ret);
904     }
905 
906     wpa2_api_unlock();
907 
908     return ret;
909 }
910 
esp_wifi_sta_wpa2_ent_set_cert_key(const unsigned char * client_cert,int client_cert_len,const unsigned char * private_key,int private_key_len,const unsigned char * private_key_passwd,int private_key_passwd_len)911 esp_err_t esp_wifi_sta_wpa2_ent_set_cert_key(const unsigned char *client_cert, int client_cert_len, const unsigned char *private_key, int private_key_len, const unsigned char *private_key_passwd, int private_key_passwd_len)
912 {
913     if (client_cert && client_cert_len > 0) {
914         g_wpa_client_cert = client_cert;
915         g_wpa_client_cert_len = client_cert_len;
916     }
917     if (private_key && private_key_len > 0) {
918         g_wpa_private_key = private_key;
919         g_wpa_private_key_len = private_key_len;
920     }
921     if (private_key_passwd && private_key_passwd_len > 0) {
922         g_wpa_private_key_passwd = private_key_passwd;
923         g_wpa_private_key_passwd_len = private_key_passwd_len;
924     }
925 
926     return ESP_OK;
927 }
928 
esp_wifi_sta_wpa2_ent_clear_cert_key(void)929 void esp_wifi_sta_wpa2_ent_clear_cert_key(void)
930 {
931     esp_wifi_unregister_wpa2_cb_internal();
932 
933     g_wpa_client_cert = NULL;
934     g_wpa_client_cert_len = 0;
935     g_wpa_private_key = NULL;
936     g_wpa_private_key_len = 0;
937     g_wpa_private_key_passwd = NULL;
938     g_wpa_private_key_passwd_len = 0;
939     os_free(g_wpa_pac_file);
940     g_wpa_pac_file = NULL;
941     g_wpa_pac_file_len = 0;
942 }
943 
esp_wifi_sta_wpa2_ent_set_ca_cert(const unsigned char * ca_cert,int ca_cert_len)944 esp_err_t esp_wifi_sta_wpa2_ent_set_ca_cert(const unsigned char *ca_cert, int ca_cert_len)
945 {
946     if (ca_cert && ca_cert_len > 0) {
947         g_wpa_ca_cert = ca_cert;
948         g_wpa_ca_cert_len = ca_cert_len;
949     }
950 
951     return ESP_OK;
952 }
953 
esp_wifi_sta_wpa2_ent_clear_ca_cert(void)954 void esp_wifi_sta_wpa2_ent_clear_ca_cert(void)
955 {
956     g_wpa_ca_cert = NULL;
957     g_wpa_ca_cert_len = 0;
958 }
959 
960 #define ANONYMOUS_ID_LEN_MAX 128
esp_wifi_sta_wpa2_ent_set_identity(const unsigned char * identity,int len)961 esp_err_t esp_wifi_sta_wpa2_ent_set_identity(const unsigned char *identity, int len)
962 {
963     if (len <= 0 || len > ANONYMOUS_ID_LEN_MAX) {
964         return ESP_ERR_INVALID_ARG;
965     }
966 
967     if (g_wpa_anonymous_identity) {
968         os_free(g_wpa_anonymous_identity);
969         g_wpa_anonymous_identity = NULL;
970     }
971 
972     g_wpa_anonymous_identity = (u8 *)os_zalloc(len);
973     if (g_wpa_anonymous_identity == NULL) {
974         return ESP_ERR_NO_MEM;
975     }
976 
977     os_memcpy(g_wpa_anonymous_identity, identity, len);
978     g_wpa_anonymous_identity_len = len;
979 
980     return ESP_OK;
981 }
982 
esp_wifi_sta_wpa2_ent_clear_identity(void)983 void esp_wifi_sta_wpa2_ent_clear_identity(void)
984 {
985     if (g_wpa_anonymous_identity) {
986         os_free(g_wpa_anonymous_identity);
987     }
988 
989     g_wpa_anonymous_identity = NULL;
990     g_wpa_anonymous_identity_len = 0;
991 }
992 
993 #define USERNAME_LEN_MAX 128
esp_wifi_sta_wpa2_ent_set_username(const unsigned char * username,int len)994 esp_err_t esp_wifi_sta_wpa2_ent_set_username(const unsigned char *username, int len)
995 {
996     if (len <= 0 || len > USERNAME_LEN_MAX) {
997         return ESP_ERR_INVALID_ARG;
998     }
999 
1000     if (g_wpa_username) {
1001         os_free(g_wpa_username);
1002         g_wpa_username = NULL;
1003     }
1004 
1005     g_wpa_username = (u8 *)os_zalloc(len);
1006     if (g_wpa_username == NULL) {
1007         return ESP_ERR_NO_MEM;
1008     }
1009 
1010     os_memcpy(g_wpa_username, username, len);
1011     g_wpa_username_len = len;
1012 
1013     return ESP_OK;
1014 }
1015 
esp_wifi_sta_wpa2_ent_clear_username(void)1016 void esp_wifi_sta_wpa2_ent_clear_username(void)
1017 {
1018     if (g_wpa_username) {
1019         os_free(g_wpa_username);
1020     }
1021 
1022     g_wpa_username = NULL;
1023     g_wpa_username_len = 0;
1024 }
1025 
esp_wifi_sta_wpa2_ent_set_password(const unsigned char * password,int len)1026 esp_err_t esp_wifi_sta_wpa2_ent_set_password(const unsigned char *password, int len)
1027 {
1028     if (len <= 0) {
1029         return ESP_ERR_INVALID_ARG;
1030     }
1031 
1032     if (g_wpa_password) {
1033         os_free(g_wpa_password);
1034         g_wpa_password = NULL;
1035     }
1036 
1037     g_wpa_password = (u8 *)os_zalloc(len);
1038     if (g_wpa_password == NULL) {
1039         return ESP_ERR_NO_MEM;
1040     }
1041 
1042     os_memcpy(g_wpa_password, password, len);
1043     g_wpa_password_len = len;
1044 
1045     return ESP_OK;
1046 }
1047 
esp_wifi_sta_wpa2_ent_clear_password(void)1048 void esp_wifi_sta_wpa2_ent_clear_password(void)
1049 {
1050     if (g_wpa_password) {
1051         os_free(g_wpa_password);
1052     }
1053     g_wpa_password = NULL;
1054     g_wpa_password_len = 0;
1055 }
1056 
esp_wifi_sta_wpa2_ent_set_new_password(const unsigned char * new_password,int len)1057 esp_err_t esp_wifi_sta_wpa2_ent_set_new_password(const unsigned char *new_password, int len)
1058 {
1059     if (len <= 0) {
1060         return ESP_ERR_INVALID_ARG;
1061     }
1062 
1063     if (g_wpa_new_password) {
1064         os_free(g_wpa_new_password);
1065         g_wpa_new_password = NULL;
1066     }
1067 
1068     g_wpa_new_password = (u8 *)os_zalloc(len);
1069     if (g_wpa_new_password == NULL) {
1070         return ESP_ERR_NO_MEM;
1071     }
1072 
1073     os_memcpy(g_wpa_new_password, new_password, len);
1074     g_wpa_password_len = len;
1075 
1076     return ESP_OK;
1077 }
1078 
esp_wifi_sta_wpa2_ent_clear_new_password(void)1079 void esp_wifi_sta_wpa2_ent_clear_new_password(void)
1080 {
1081     if (g_wpa_new_password) {
1082         os_free(g_wpa_new_password);
1083     }
1084     g_wpa_new_password = NULL;
1085     g_wpa_new_password_len = 0;
1086 }
1087 
esp_wifi_sta_wpa2_ent_set_disable_time_check(bool disable)1088 esp_err_t esp_wifi_sta_wpa2_ent_set_disable_time_check(bool disable)
1089 {
1090     s_disable_time_check = disable;
1091     return ESP_OK;
1092 }
1093 
wifi_sta_get_enterprise_disable_time_check(void)1094 bool wifi_sta_get_enterprise_disable_time_check(void)
1095 {
1096     return s_disable_time_check;
1097 }
1098 
esp_wifi_sta_wpa2_ent_get_disable_time_check(bool * disable)1099 esp_err_t esp_wifi_sta_wpa2_ent_get_disable_time_check(bool *disable)
1100 {
1101     *disable = wifi_sta_get_enterprise_disable_time_check();
1102     return ESP_OK;
1103 }
1104 
esp_wifi_sta_wpa2_ent_set_ttls_phase2_method(esp_eap_ttls_phase2_types type)1105 esp_err_t esp_wifi_sta_wpa2_ent_set_ttls_phase2_method(esp_eap_ttls_phase2_types type)
1106 {
1107     switch (type) {
1108         case ESP_EAP_TTLS_PHASE2_EAP:
1109             g_wpa_ttls_phase2_type = "auth=EAP";
1110             break;
1111         case ESP_EAP_TTLS_PHASE2_MSCHAPV2:
1112             g_wpa_ttls_phase2_type = "auth=MSCHAPV2";
1113             break;
1114         case ESP_EAP_TTLS_PHASE2_MSCHAP:
1115             g_wpa_ttls_phase2_type = "auth=MSCHAP";
1116             break;
1117         case ESP_EAP_TTLS_PHASE2_PAP:
1118             g_wpa_ttls_phase2_type = "auth=PAP";
1119             break;
1120         case ESP_EAP_TTLS_PHASE2_CHAP:
1121             g_wpa_ttls_phase2_type = "auth=CHAP";
1122             break;
1123         default:
1124             g_wpa_ttls_phase2_type = "auth=MSCHAPV2";
1125             break;
1126     }
1127     return ESP_OK;
1128 }
1129 
esp_wifi_sta_wpa2_set_suiteb_192bit_certification(bool enable)1130 esp_err_t esp_wifi_sta_wpa2_set_suiteb_192bit_certification(bool enable)
1131 {
1132 #ifdef CONFIG_SUITEB192
1133     g_wpa_suiteb_certification = enable;
1134     return ESP_OK;
1135 #else
1136     return ESP_FAIL;
1137 #endif
1138 }
1139 
esp_wifi_sta_wpa2_ent_set_pac_file(const unsigned char * pac_file,int pac_file_len)1140 esp_err_t esp_wifi_sta_wpa2_ent_set_pac_file(const unsigned char *pac_file, int pac_file_len)
1141 {
1142     if (pac_file && pac_file_len > -1) {
1143         if (pac_file_len < 512) { // The file contains less than 1 pac and is to be rewritten later
1144             g_wpa_pac_file = (u8 *)os_zalloc(512);
1145             if (g_wpa_pac_file == NULL) {
1146                 return ESP_ERR_NO_MEM;
1147             }
1148             g_wpa_pac_file_len = 0;
1149         } else { // The file contains pac data
1150             g_wpa_pac_file = (u8 *)os_zalloc(pac_file_len);
1151             if (g_wpa_pac_file == NULL) {
1152                 return ESP_ERR_NO_MEM;
1153             }
1154             os_memcpy(g_wpa_pac_file, pac_file, pac_file_len);
1155             g_wpa_pac_file_len = pac_file_len;
1156         }
1157     } else {
1158         return ESP_FAIL;
1159     }
1160 
1161     return ESP_OK;
1162 }
1163 
esp_wifi_sta_wpa2_ent_set_fast_phase1_params(esp_eap_fast_config config)1164 esp_err_t esp_wifi_sta_wpa2_ent_set_fast_phase1_params(esp_eap_fast_config config)
1165 {
1166     char config_for_supplicant[PHASE1_PARAM_STRING_LEN] = "";
1167     if ((config.fast_provisioning > -1) && (config.fast_provisioning <= 2)) {
1168         os_sprintf((char *) &config_for_supplicant, "fast_provisioning=%d ", config.fast_provisioning);
1169     } else {
1170         return ESP_ERR_INVALID_ARG;
1171     }
1172     if (config.fast_max_pac_list_len && config.fast_max_pac_list_len < 100) {
1173         os_sprintf((char *) &config_for_supplicant + strlen(config_for_supplicant), "fast_max_pac_list_len=%d ", config.fast_max_pac_list_len);
1174     } else if (config.fast_max_pac_list_len >= 100) {
1175         return ESP_ERR_INVALID_ARG;
1176     }
1177     if (config.fast_pac_format_binary) {
1178         os_strcat((char *) &config_for_supplicant, (const char *) "fast_pac_format=binary");
1179     }
1180 
1181     // Free the old buffer if it already exists
1182     if (g_wpa_phase1_options != NULL) {
1183         os_free(g_wpa_phase1_options);
1184     }
1185     g_wpa_phase1_options = (char *)os_zalloc(sizeof(config_for_supplicant));
1186     if (g_wpa_phase1_options == NULL) {
1187         return ESP_ERR_NO_MEM;
1188     }
1189     os_memcpy(g_wpa_phase1_options, &config_for_supplicant, sizeof(config_for_supplicant));
1190     return ESP_OK;
1191 
1192 }
1193