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