From e716bb876d46938416e1d65aa123fac875745e97 Mon Sep 17 00:00:00 2001 From: Zhang Jun Hao Date: Tue, 18 Aug 2020 10:25:17 +0800 Subject: [PATCH] feat(wpa_supplicant): refactor wpa_supplicant --- components/esp8266/include/esp_private/wifi.h | 42 + components/esp8266/include/esp_wifi_types.h | 10 +- components/esp8266/include/rom/ets_sys.h | 10 + components/esp8266/source/esp_wifi.c | 70 +- components/wpa_supplicant/CMakeLists.txt | 11 +- components/wpa_supplicant/component.mk | 2 +- .../include/esp_supplicant/esp_wpa2.h | 14 +- .../include/esp_supplicant/esp_wps.h | 4 - components/wpa_supplicant/src/ap/wpa_auth.c | 106 +- components/wpa_supplicant/src/ap/wpa_auth_i.h | 1 + .../wpa_supplicant/src/crypto/tls_mbedtls.c | 3 +- .../wpa_supplicant/src/eap_peer/eap_i.h | 10 +- .../src/esp_supplicant/esp_hostap.c | 136 + .../src/esp_supplicant/esp_wifi_driver.h | 144 ++ .../src/esp_supplicant/esp_wpa2.c | 910 ++++++- .../src/esp_supplicant/esp_wpa3.c | 17 +- .../src/esp_supplicant/esp_wpa3_i.h | 7 + .../src/esp_supplicant/esp_wpa_main.c | 193 +- .../src/esp_supplicant/esp_wpas_glue.c | 12 +- .../src/esp_supplicant/esp_wps.c | 2196 +++++++++++++++++ .../src/fast_crypto/fast_aes-cbc.c | 82 - .../src/fast_crypto/fast_aes-unwrap.c | 87 - .../src/fast_crypto/fast_aes-wrap.c | 88 - .../fast_crypto/fast_crypto_internal-cipher.c | 290 --- .../fast_crypto/fast_crypto_internal-modexp.c | 64 - .../src/fast_crypto/fast_crypto_internal.c | 289 --- .../src/fast_crypto/fast_crypto_ops.c | 253 -- .../src/fast_crypto/fast_sha256-internal.c | 62 - .../src/fast_crypto/fast_sha256.c | 170 -- components/wpa_supplicant/src/rsn_supp/wpa.c | 30 +- components/wpa_supplicant/src/rsn_supp/wpa.h | 3 + .../wpa_supplicant/src/rsn_supp/wpa_i.h | 2 +- components/wpa_supplicant/src/wps/wps.h | 30 +- .../wpa_supplicant/src/wps/wps_enrollee.c | 9 +- components/wpa_supplicant/src/wps/wps_i.h | 34 - .../main/wpa2_enterprise_main.c | 3 +- 36 files changed, 3764 insertions(+), 1630 deletions(-) mode change 100644 => 100755 components/wpa_supplicant/include/esp_supplicant/esp_wpa2.h create mode 100755 components/wpa_supplicant/src/esp_supplicant/esp_hostap.c mode change 100644 => 100755 components/wpa_supplicant/src/esp_supplicant/esp_wpa2.c create mode 100755 components/wpa_supplicant/src/esp_supplicant/esp_wps.c delete mode 100644 components/wpa_supplicant/src/fast_crypto/fast_aes-cbc.c delete mode 100644 components/wpa_supplicant/src/fast_crypto/fast_aes-unwrap.c delete mode 100644 components/wpa_supplicant/src/fast_crypto/fast_aes-wrap.c delete mode 100644 components/wpa_supplicant/src/fast_crypto/fast_crypto_internal-cipher.c delete mode 100644 components/wpa_supplicant/src/fast_crypto/fast_crypto_internal-modexp.c delete mode 100644 components/wpa_supplicant/src/fast_crypto/fast_crypto_internal.c delete mode 100644 components/wpa_supplicant/src/fast_crypto/fast_crypto_ops.c delete mode 100644 components/wpa_supplicant/src/fast_crypto/fast_sha256-internal.c delete mode 100644 components/wpa_supplicant/src/fast_crypto/fast_sha256.c diff --git a/components/esp8266/include/esp_private/wifi.h b/components/esp8266/include/esp_private/wifi.h index 687c0790..8c8042c6 100644 --- a/components/esp8266/include/esp_private/wifi.h +++ b/components/esp8266/include/esp_private/wifi.h @@ -15,6 +15,10 @@ #ifndef _ESP_WIFI_INTERNAL_H #define _ESP_WIFI_INTERNAL_H +#include "esp_wifi_types.h" +#include "esp_event.h" +#include "esp_wifi.h" + #ifdef __cplusplus extern "C" { #endif @@ -58,6 +62,44 @@ typedef enum { #define WIFI_LOG_SUBMODULE_FRAG (1<<14) #define WIFI_LOG_SUBMODULE_WPA2 (1<<15) + +/** + * @brief Initialize Wi-Fi Driver + * Alloc resource for WiFi driver, such as WiFi control structure, RX/TX buffer, + * WiFi NVS structure among others. + * + * For the most part, you need not call this function directly. It gets called + * from esp_wifi_init(). + * + * This function may be called, if you only need to initialize the Wi-Fi driver + * without having to use the network stack on top. + * + * @param config provide WiFi init configuration + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_NO_MEM: out of memory + * - others: refer to error code esp_err.h + */ +esp_err_t esp_wifi_init_internal(const wifi_init_config_t *config); + +/** + * @brief Deinitialize Wi-Fi Driver + * Free resource for WiFi driver, such as WiFi control structure, RX/TX buffer, + * WiFi NVS structure among others. + * + * For the most part, you need not call this function directly. It gets called + * from esp_wifi_deinit(). + * + * This function may be called, if you call esp_wifi_init_internal to initialize + * WiFi driver. + * + * @return + * - ESP_OK: succeed + * - others: refer to error code esp_err.h + */ +esp_err_t esp_wifi_deinit_internal(void); + /** * @brief Set WIFI received TCP/IP data cache ram type * diff --git a/components/esp8266/include/esp_wifi_types.h b/components/esp8266/include/esp_wifi_types.h index cbd44e57..9b7c413e 100755 --- a/components/esp8266/include/esp_wifi_types.h +++ b/components/esp8266/include/esp_wifi_types.h @@ -89,12 +89,16 @@ typedef enum { WIFI_REASON_802_1X_AUTH_FAILED = 23, WIFI_REASON_CIPHER_SUITE_REJECTED = 24, + WIFI_REASON_INVALID_PMKID = 53, + WIFI_REASON_BEACON_TIMEOUT = 200, WIFI_REASON_NO_AP_FOUND = 201, WIFI_REASON_AUTH_FAIL = 202, WIFI_REASON_ASSOC_FAIL = 203, WIFI_REASON_HANDSHAKE_TIMEOUT = 204, - WIFI_REASON_BASIC_RATE_NOT_SUPPORT = 205, + WIFI_REASON_CONNECTION_FAIL = 205, + WIFI_REASON_AP_TSF_RESET = 206, + WIFI_REASON_BASIC_RATE_NOT_SUPPORT = 207, } wifi_err_reason_t; typedef enum { @@ -517,6 +521,10 @@ typedef struct { wifi_auth_mode_t new_mode; /**< the new auth mode of AP */ } wifi_event_sta_authmode_change_t; +#define MAX_SSID_LEN 32 +#define MAX_PASSPHRASE_LEN 64 +#define MAX_WPS_AP_CRED 3 + /** Argument structure for WIFI_EVENT_STA_WPS_ER_PIN event */ typedef struct { uint8_t pin_code[8]; /**< PIN code of station in enrollee mode */ diff --git a/components/esp8266/include/rom/ets_sys.h b/components/esp8266/include/rom/ets_sys.h index 1d55805e..136a2167 100644 --- a/components/esp8266/include/rom/ets_sys.h +++ b/components/esp8266/include/rom/ets_sys.h @@ -60,6 +60,16 @@ void vPortETSIntrUnlock(void); #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" +typedef uint32_t ETSSignal; +typedef uint32_t ETSParam; + +typedef struct ETSEventTag ETSEvent; /**< Event transmit/receive in ets*/ + +struct ETSEventTag { + ETSSignal sig; /**< Event signal, in same task, different Event with different signal*/ + ETSParam par; /**< Event parameter, sometimes without usage, then will be set as 0*/ +}; + /** * @brief Delay function, maximum value: 65535 us. * diff --git a/components/esp8266/source/esp_wifi.c b/components/esp8266/source/esp_wifi.c index 4fe6d906..5524c343 100644 --- a/components/esp8266/source/esp_wifi.c +++ b/components/esp8266/source/esp_wifi.c @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#include #include "sdkconfig.h" #include "esp_libc.h" #include "esp_system.h" @@ -19,6 +21,8 @@ #include "esp_log.h" #include "esp_private/wifi.h" #include "phy.h" +#include "esp_supplicant/esp_wpa.h" +#include "esp_aio.h" #define TAG "wifi_init" @@ -30,8 +34,10 @@ const bool _g_esp_wifi_connect_open_router_when_pwd_is_set = true; const bool _g_esp_wifi_connect_open_router_when_pwd_is_set = false; #endif +#define EP_OFFSET 36 +int ieee80211_output_pbuf(esp_aio_t *aio); + esp_err_t mac_init(void); -esp_err_t esp_wifi_init_internal(const wifi_init_config_t *config); ESP_EVENT_DEFINE_BASE(WIFI_EVENT); @@ -109,6 +115,19 @@ static void esp_wifi_set_debug_log() #endif /* CONFIG_ESP8266_WIFI_DEBUG_LOG_ENABLE*/ } +esp_err_t esp_wifi_deinit(void) +{ + esp_err_t err = ESP_OK; + + esp_supplicant_deinit(); + err = esp_wifi_deinit_internal(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to deinit Wi-Fi driver (0x%x)", err); + return err; + } + return err; +} + /** * @brief Init WiFi * Alloc resource for WiFi driver, such as WiFi control structure, RX/TX buffer, @@ -137,6 +156,16 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) esp_err_t result = esp_wifi_init_internal(config); if (result == ESP_OK) { esp_wifi_set_debug_log(); + result = esp_supplicant_init(); + if (result != ESP_OK) { + ESP_LOGE(TAG, "Failed to init supplicant (0x%x)", result); + esp_err_t deinit_ret = esp_wifi_deinit(); + if (deinit_ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to deinit Wi-Fi (0x%x)", deinit_ret); + } + + return result; + } } result = tcpip_adapter_set_default_wifi_handlers(); @@ -169,3 +198,42 @@ bool IRAM_ATTR esp_wifi_try_rate_from_high(void) { #endif return false; } + +int wifi_internal_send_cb(esp_aio_t* aio) +{ + char* pb = (char*)aio->arg; + + if (pb) { + os_free(pb); + pb = NULL; + } + + return ESP_OK; +} + +int esp_wifi_internal_tx(wifi_interface_t wifi_if, void *buffer, uint16_t len) +{ + esp_aio_t aio; + esp_err_t ret = ESP_OK; + uint8_t *dram_buffer = (uint8_t *)heap_caps_malloc(len + EP_OFFSET, MALLOC_CAP_8BIT); + if (!dram_buffer) { + return ESP_ERR_NO_MEM; + } + dram_buffer = ((uint8_t *)dram_buffer + EP_OFFSET); + memcpy(dram_buffer, buffer, len); + + aio.arg = (char *)dram_buffer - EP_OFFSET; + aio.cb = wifi_internal_send_cb; + aio.fd = wifi_if; + aio.pbuf = (char *)dram_buffer; + aio.len = len; + aio.ret = 0; + ret = ieee80211_output_pbuf(&aio); + + if(ret != 0) { + os_free(aio.arg); + } + + return ret; +} + diff --git a/components/wpa_supplicant/CMakeLists.txt b/components/wpa_supplicant/CMakeLists.txt index 0069a33b..c635717e 100644 --- a/components/wpa_supplicant/CMakeLists.txt +++ b/components/wpa_supplicant/CMakeLists.txt @@ -56,19 +56,12 @@ set(srcs "port/os_xtensa.c" "src/eap_peer/eap_tls_common.c" "src/eap_peer/eap_ttls.c" "src/eap_peer/mschapv2.c" + "src/esp_supplicant/esp_hostap.c" "src/esp_supplicant/esp_wpa2.c" "src/esp_supplicant/esp_wpa_main.c" "src/esp_supplicant/esp_wpas_glue.c" + "src/esp_supplicant/esp_wps.c" "src/esp_supplicant/esp_wpa3.c" - "src/fast_crypto/fast_aes-cbc.c" - "src/fast_crypto/fast_aes-unwrap.c" - "src/fast_crypto/fast_aes-wrap.c" - "src/fast_crypto/fast_crypto_internal.c" - "src/fast_crypto/fast_crypto_internal-cipher.c" - "src/fast_crypto/fast_crypto_internal-modexp.c" - "src/fast_crypto/fast_crypto_ops.c" - "src/fast_crypto/fast_sha256.c" - "src/fast_crypto/fast_sha256-internal.c" "src/rsn_supp/pmksa_cache.c" "src/rsn_supp/wpa.c" "src/rsn_supp/wpa_ie.c" diff --git a/components/wpa_supplicant/component.mk b/components/wpa_supplicant/component.mk index af2369cf..73f48a52 100644 --- a/components/wpa_supplicant/component.mk +++ b/components/wpa_supplicant/component.mk @@ -1,7 +1,7 @@ # supplicant make file COMPONENT_PRIV_INCLUDEDIRS := src -COMPONENT_SRCDIRS := port src/ap src/common src/crypto src/eap_peer src/fast_crypto src/rsn_supp src/tls src/utils src/esp_supplicant src/wps +COMPONENT_SRCDIRS := port src/ap src/common src/crypto src/eap_peer src/rsn_supp src/tls src/utils src/esp_supplicant src/wps COMPONENT_ADD_INCLUDEDIRS := include port/include include/esp_supplicant ifeq ($(CONFIG_WPA_MBEDTLS_CRYPTO), y) diff --git a/components/wpa_supplicant/include/esp_supplicant/esp_wpa2.h b/components/wpa_supplicant/include/esp_supplicant/esp_wpa2.h old mode 100644 new mode 100755 index 834027ae..53156065 --- a/components/wpa_supplicant/include/esp_supplicant/esp_wpa2.h +++ b/components/wpa_supplicant/include/esp_supplicant/esp_wpa2.h @@ -16,23 +16,13 @@ #define _ESP_WPA2_H #include -#include "esp_wifi_crypto_types.h" + #include "esp_err.h" #ifdef __cplusplus extern "C" { #endif -extern const wpa2_crypto_funcs_t g_wifi_default_wpa2_crypto_funcs; - -typedef struct { - const wpa2_crypto_funcs_t *crypto_funcs; -}esp_wpa2_config_t; - -#define WPA2_CONFIG_INIT_DEFAULT() { \ - .crypto_funcs = &g_wifi_default_wpa2_crypto_funcs \ -} - /** * @brief Enable wpa2 enterprise authentication. * @@ -43,7 +33,7 @@ typedef struct { * - ESP_OK: succeed. * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) */ -esp_err_t esp_wifi_sta_wpa2_ent_enable(const esp_wpa2_config_t *config); +esp_err_t esp_wifi_sta_wpa2_ent_enable(void); /** * @brief Disable wpa2 enterprise authentication. diff --git a/components/wpa_supplicant/include/esp_supplicant/esp_wps.h b/components/wpa_supplicant/include/esp_supplicant/esp_wps.h index 28163577..646a9173 100644 --- a/components/wpa_supplicant/include/esp_supplicant/esp_wps.h +++ b/components/wpa_supplicant/include/esp_supplicant/esp_wps.h @@ -55,8 +55,6 @@ typedef enum wps_type { WPS_TYPE_MAX, } wps_type_t; -extern const wps_crypto_funcs_t g_wifi_default_wps_crypto_funcs; - #define WPS_MAX_MANUFACTURER_LEN 65 #define WPS_MAX_MODEL_NUMBER_LEN 33 #define WPS_MAX_MODEL_NAME_LEN 33 @@ -71,13 +69,11 @@ typedef struct { typedef struct { wps_type_t wps_type; - const wps_crypto_funcs_t *crypto_funcs; wps_factory_information_t factory_info; } esp_wps_config_t; #define WPS_CONFIG_INIT_DEFAULT(type) { \ .wps_type = type, \ - .crypto_funcs = &g_wifi_default_wps_crypto_funcs, \ .factory_info = { \ ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(manufacturer, "ESPRESSIF") \ ESP_COMPILER_DESIGNATED_INIT_AGGREGATE_TYPE_STR(model_number, "ESP8266") \ diff --git a/components/wpa_supplicant/src/ap/wpa_auth.c b/components/wpa_supplicant/src/ap/wpa_auth.c index 9ef02427..8b430987 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth.c +++ b/components/wpa_supplicant/src/ap/wpa_auth.c @@ -27,9 +27,7 @@ #include "esp_supplicant/esp_wifi_driver.h" #include "esp_wifi.h" - -#define wpa_malloc_dram(s) heap_caps_malloc(s, MALLOC_CAP_8BIT) -#define wpa_calloc_dram(n, s) heap_caps_calloc(n, s, MALLOC_CAP_8BIT) +#include "esp_private/wifi.h" #define STATE_MACHINE_DATA struct wpa_state_machine #define STATE_MACHINE_DEBUG_PREFIX "WPA" @@ -57,8 +55,6 @@ static const u32 eapol_key_timeout_first_group = 500; /* ms */ static void *s_sm_table[WPA_SM_MAX_INDEX]; static u32 s_sm_valid_bitmap = 0; -ETSTimer resend_eapol; - static struct wpa_state_machine * wpa_auth_get_sm(u32 index) { if ( (index < WPA_SM_MAX_INDEX) && (BIT(index) & s_sm_valid_bitmap)){ @@ -153,79 +149,28 @@ static inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth, return -1; } -#include "esp_aio.h" -int ieee80211_output_pbuf(esp_aio_t *aio); -#define EP_OFFSET 36 /* fix buf for tx for now */ #define WPA_TX_MSG_BUFF_MAXLEN 200 -static int wpa_auth_send_cb(esp_aio_t* aio) -{ - char* pb = (char*)aio->arg; - - os_free(pb); - - return 0; -} - static inline int wpa_auth_send_eapol(struct wpa_authenticator *wpa_auth, const u8 *addr, const u8 *data, size_t data_len, int encrypt) { - // wujg : need to add send data function + void *buffer = os_malloc(256); + struct l2_ethhdr *eth = buffer; -#ifndef IOT_SIP_MODE - esp_aio_t aio; - uint8_t* pb = wpa_malloc_dram(data_len + EP_OFFSET + sizeof(struct l2_ethhdr)); - struct l2_ethhdr* eth; - u8 mac[6]; - pb = pb + EP_OFFSET; - esp_wifi_get_mac(WIFI_IF_AP, mac); - - if (pb == NULL) { - wpa_printf( MSG_DEBUG, "send_eapol, buffer=%p\n", pb); + if (!buffer){ + wpa_printf( MSG_DEBUG, "send_eapol, buffer=%p\n", buffer); return -1; } - eth = (struct l2_ethhdr*)pb; - os_memcpy(eth->h_dest, addr, ETH_ALEN); - os_memcpy(eth->h_source, mac, ETH_ALEN); + memcpy(eth->h_dest, addr, ETH_ALEN); + memcpy(eth->h_source, wpa_auth->addr, ETH_ALEN); eth->h_proto = host_to_be16(ETH_P_EAPOL); - os_memcpy((uint8_t*)pb + sizeof(struct l2_ethhdr), data, data_len); - - aio.arg = pb - EP_OFFSET; - aio.cb = wpa_auth_send_cb; - aio.fd = 1; - aio.pbuf = (char *)pb; - aio.len = sizeof(struct l2_ethhdr) + data_len; - aio.ret = 0; - - if (ieee80211_output_pbuf(&aio) != 0) { - os_free(pb - EP_OFFSET); - wpa_printf(MSG_INFO, "wpa_auth_send_eapol failed"); - return -1; - } - -#else - esf_buf* eb = NULL; - struct l2_ethhdr* eth; - uint8_t* frm; - - eb = ieee80211_getmgtframe(&frm, sizeof(struct ieee80211_frame), WPA_TX_MSG_BUFF_MAXLEN); - eth = etod(eb, struct l2_ethhdr); - os_memcpy(eth->h_dest, addr, ETH_ALEN); - os_memcpy(eth->h_source, g_ic.ic_if1_conn->ni_myaddr, ETH_ALEN); - eth->h_proto = host_to_be16(ETH_P_EAPOL); - - os_memcpy(frm + sizeof(struct l2_ethhdr), data, data_len); - - eb->hdr_len = sizeof(struct ieee80211_frame); - eb->data_len = sizeof(struct l2_ethhdr) + data_len; - - ieee80211_output_pbuf(g_ic.ic_if1_conn, eb); -#endif - + memcpy((char *)buffer + sizeof(struct l2_ethhdr), data, data_len); + esp_wifi_internal_tx(1, buffer, sizeof(struct l2_ethhdr) + data_len); + os_free(buffer); return 0; } @@ -239,9 +184,8 @@ int wpa_auth_for_each_sta(struct wpa_authenticator *wpa_auth, static void wpa_sta_disconnect(struct wpa_authenticator *wpa_auth, const u8 *addr) { - // wujg : need to add disconnect function wpa_printf(MSG_DEBUG, "wpa_sta_disconnect STA " MACSTR, MAC2STR(addr)); - //esp_wifi_ap_deauth_internal((uint8_t*)addr, WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT); + esp_wifi_ap_deauth_internal((uint8_t*)addr, WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT); return; } @@ -490,8 +434,8 @@ void wpa_auth_sta_deinit(struct wpa_state_machine *sm) if (sm == NULL) return; - ets_timer_disarm(&resend_eapol); - ets_timer_done(&resend_eapol); + ets_timer_disarm(&sm->resend_eapol); + ets_timer_done(&sm->resend_eapol); if (sm->in_step_loop) { /* Must not free state machine while wpa_sm_step() is running. @@ -870,8 +814,8 @@ continue_processing: } sm->MICVerified = TRUE; eloop_cancel_timeout(wpa_send_eapol_timeout, wpa_auth, sm); - ets_timer_disarm(&resend_eapol); - ets_timer_done(&resend_eapol); + ets_timer_disarm(&sm->resend_eapol); + ets_timer_done(&sm->resend_eapol); sm->pending_1_of_4_timeout = 0; } @@ -1155,7 +1099,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth, os_free(hdr); } -void resend_eapol_handle(void *timeout_ctx) +int hostap_eapol_resend_process(void *timeout_ctx) { u32 index = (u32)timeout_ctx; struct wpa_state_machine *sm = wpa_auth_get_sm(index); @@ -1170,6 +1114,18 @@ void resend_eapol_handle(void *timeout_ctx) } else { wpa_printf( MSG_INFO, "Station left, stop send EAPOL frame"); } + + return ESP_OK; +} + +void resend_eapol_handle(void *timeout_ctx) +{ + wifi_ipc_config_t cfg; + + cfg.fn = hostap_eapol_resend_process; + cfg.arg = timeout_ctx; + cfg.arg_size = 0; + esp_wifi_ipc_internal(&cfg, false); } static void wpa_send_eapol(struct wpa_authenticator *wpa_auth, @@ -1200,9 +1156,9 @@ static void wpa_send_eapol(struct wpa_authenticator *wpa_auth, "counter %d)\n", timeout_ms, ctr); eloop_register_timeout(timeout_ms / 1000, (timeout_ms % 1000) * 1000, wpa_send_eapol_timeout, wpa_auth, sm); - ets_timer_disarm(&resend_eapol); - ets_timer_setfn(&resend_eapol, (ETSTimerFunc *)resend_eapol_handle, (void*)(sm->index)); - ets_timer_arm(&resend_eapol, 1000, 0); + ets_timer_disarm(&sm->resend_eapol); + ets_timer_setfn(&sm->resend_eapol, (ETSTimerFunc *)resend_eapol_handle, (void*)(sm->index)); + ets_timer_arm(&sm->resend_eapol, 1000, 0); } diff --git a/components/wpa_supplicant/src/ap/wpa_auth_i.h b/components/wpa_supplicant/src/ap/wpa_auth_i.h index f795695f..6a55cdee 100755 --- a/components/wpa_supplicant/src/ap/wpa_auth_i.h +++ b/components/wpa_supplicant/src/ap/wpa_auth_i.h @@ -117,6 +117,7 @@ struct wpa_state_machine { int pending_1_of_4_timeout; u32 index; + ETSTimer resend_eapol; }; diff --git a/components/wpa_supplicant/src/crypto/tls_mbedtls.c b/components/wpa_supplicant/src/crypto/tls_mbedtls.c index c26ed7a6..409281ff 100644 --- a/components/wpa_supplicant/src/crypto/tls_mbedtls.c +++ b/components/wpa_supplicant/src/crypto/tls_mbedtls.c @@ -384,7 +384,7 @@ static void tls_set_ciphersuite(tls_context_t *tls) if (tls->ciphersuite[0]) { mbedtls_ssl_conf_ciphersuites(&tls->conf, tls->ciphersuite); } else if (mbedtls_pk_get_bitlen(&tls->clientkey) > 2048 || - mbedtls_pk_get_bitlen(&tls->cacert_ptr->pk) > 2048) { + (tls->cacert_ptr && mbedtls_pk_get_bitlen(&tls->cacert_ptr->pk) > 2048)) { mbedtls_ssl_conf_ciphersuites(&tls->conf, eap_ciphersuite_preference); } } @@ -504,6 +504,7 @@ void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn) { /* Free ssl ctx and data */ tls_mbedtls_conn_delete((tls_context_t *) conn->tls); + os_free(conn->tls); conn->tls = NULL; /* Data in in ssl ctx, free connection */ os_free(conn); diff --git a/components/wpa_supplicant/src/eap_peer/eap_i.h b/components/wpa_supplicant/src/eap_peer/eap_i.h index 5d76db61..a55a8ae3 100644 --- a/components/wpa_supplicant/src/eap_peer/eap_i.h +++ b/components/wpa_supplicant/src/eap_peer/eap_i.h @@ -98,6 +98,13 @@ struct eap_method { #define BLOB_NAME_LEN 3 #define BLOB_NUM 3 +enum SIG_WPA2 { + SIG_WPA2_START = 0, + SIG_WPA2_RX, + SIG_WPA2_TASK_DEL, + SIG_WPA2_MAX, +}; + /** * struct eap_sm - EAP state machine data */ @@ -114,8 +121,7 @@ struct eap_sm { u8 current_identifier; u8 ownaddr[ETH_ALEN]; #ifdef USE_WPA2_TASK -#define SIG_WPA2_NUM 2 - u8 wpa2_sig_cnt[SIG_WPA2_NUM]; + u8 wpa2_sig_cnt[SIG_WPA2_MAX]; #endif u8 finish_state; diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_hostap.c b/components/wpa_supplicant/src/esp_supplicant/esp_hostap.c new file mode 100755 index 00000000..11a0564a --- /dev/null +++ b/components/wpa_supplicant/src/esp_supplicant/esp_hostap.c @@ -0,0 +1,136 @@ +// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "utils/includes.h" + +#include "utils/common.h" +#include "crypto/sha1.h" +#include "common/ieee802_11_defs.h" +#include "common/eapol_common.h" +#include "ap/wpa_auth.h" +#include "ap/ap_config.h" +#include "utils/wpa_debug.h" +#include "ap/hostapd.h" +#include "ap/wpa_auth_i.h" +#include "esp_wifi_driver.h" +#include "esp_wifi_types.h" + +void *hostap_init(void) +{ + struct wifi_ssid *ssid = esp_wifi_ap_get_prof_ap_ssid_internal(); + struct hostapd_data *hapd = NULL; + struct wpa_auth_config *auth_conf; + u8 mac[6]; + + hapd = (struct hostapd_data *)os_zalloc(sizeof(struct hostapd_data)); + + if (hapd == NULL) { + return NULL; + } + + hapd->conf = (struct hostapd_bss_config *)os_zalloc(sizeof(struct hostapd_bss_config)); + + if (hapd->conf == NULL) { + os_free(hapd); + return NULL; + } + + auth_conf = (struct wpa_auth_config *)os_zalloc(sizeof(struct wpa_auth_config)); + + if (auth_conf == NULL) { + os_free(hapd->conf); + os_free(hapd); + hapd = NULL; + return NULL; + } + if (esp_wifi_ap_get_prof_authmode_internal() == WIFI_AUTH_WPA_PSK) { + auth_conf->wpa = WPA_PROTO_WPA; + } + if (esp_wifi_ap_get_prof_authmode_internal() == WIFI_AUTH_WPA2_PSK) { + auth_conf->wpa = WPA_PROTO_RSN; + } + if (esp_wifi_ap_get_prof_authmode_internal() == WIFI_AUTH_WPA_WPA2_PSK) { + auth_conf->wpa = WPA_PROTO_RSN | WPA_PROTO_WPA; + } + + auth_conf->wpa_group = WPA_CIPHER_TKIP; + auth_conf->wpa_pairwise = WPA_CIPHER_CCMP | WPA_CIPHER_TKIP; + auth_conf->rsn_pairwise = WPA_CIPHER_CCMP | WPA_CIPHER_TKIP; + auth_conf->wpa_key_mgmt = WPA_KEY_MGMT_PSK; + auth_conf->eapol_version = EAPOL_VERSION; + + memcpy(hapd->conf->ssid.ssid, ssid->ssid, ssid->len); + hapd->conf->ssid.ssid_len = ssid->len; + hapd->conf->ssid.wpa_passphrase = (char *)os_zalloc(64); + if (hapd->conf->ssid.wpa_passphrase == NULL) { + os_free(auth_conf); + os_free(hapd->conf); + os_free(hapd); + hapd = NULL; + return NULL; + } + memcpy(hapd->conf->ssid.wpa_passphrase, esp_wifi_ap_get_prof_password_internal(), strlen((char *)esp_wifi_ap_get_prof_password_internal())); + + hapd->conf->ap_max_inactivity = 5 * 60; + hostapd_setup_wpa_psk(hapd->conf); + + esp_wifi_get_macaddr_internal(WIFI_IF_AP, mac); + + hapd->wpa_auth = wpa_init(mac, auth_conf, NULL); + esp_wifi_set_appie_internal(WIFI_APPIE_WPA, hapd->wpa_auth->wpa_ie, (uint16_t)hapd->wpa_auth->wpa_ie_len, 0); + os_free(auth_conf); + + return (void *)hapd; +} + +bool hostap_deinit(void *data) +{ + struct hostapd_data *hapd = (struct hostapd_data *)data; + + if (hapd == NULL) { + return true; + } + + if (hapd->wpa_auth->wpa_ie != NULL) { + os_free(hapd->wpa_auth->wpa_ie); + } + + if (hapd->wpa_auth->group != NULL) { + os_free(hapd->wpa_auth->group); + } + + if (hapd->wpa_auth != NULL) { + os_free(hapd->wpa_auth); + } + + if (hapd->conf->ssid.wpa_psk != NULL) { + os_free(hapd->conf->ssid.wpa_psk); + } + + if (hapd->conf->ssid.wpa_passphrase != NULL) { + os_free(hapd->conf->ssid.wpa_passphrase); + } + + if (hapd->conf != NULL) { + os_free(hapd->conf); + } + + if (hapd != NULL) { + os_free(hapd); + } + + esp_wifi_unset_appie_internal(WIFI_APPIE_WPA); + + return true; +} diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_wifi_driver.h b/components/wpa_supplicant/src/esp_supplicant/esp_wifi_driver.h index 4cb558be..77b5d4a5 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_wifi_driver.h +++ b/components/wpa_supplicant/src/esp_supplicant/esp_wifi_driver.h @@ -18,6 +18,30 @@ #include "esp_err.h" #include "esp_wifi.h" +#if CONFIG_NEWLIB_NANO_FORMAT +#define TASK_STACK_SIZE_ADD 0 +#else +#define TASK_STACK_SIZE_ADD 512 +#endif + +#define WPA2_TASK_STACK_SIZE (6144 + TASK_STACK_SIZE_ADD) +#define WPS_TASK_STACK_SIZE (12288 + TASK_STACK_SIZE_ADD) + +enum { + WIFI_APPIE_PROBEREQ = 0, + WIFI_APPIE_ASSOC_REQ, + WIFI_APPIE_ASSOC_RESP, + WIFI_APPIE_WPA, + WIFI_APPIE_RSN, + WIFI_APPIE_WPS_PR, + WIFI_APPIE_WPS_AR, + WIFI_APPIE_MESH_QUICK, + WIFI_APPIE_FREQ_ERROR, + WIFI_APPIE_ESP_MANUFACTOR, + WIFI_APPIE_COUNTRY, + WIFI_APPIE_MAX, +}; + enum { NONE_AUTH = 0x01, WPA_AUTH_UNSPEC = 0x02, @@ -31,11 +55,100 @@ enum { WPA2_AUTH_INVALID = 0x0a, }; +typedef enum { + WPA2_ENT_EAP_STATE_NOT_START, + WPA2_ENT_EAP_STATE_IN_PROGRESS, + WPA2_ENT_EAP_STATE_SUCCESS, + WPA2_ENT_EAP_STATE_FAIL, +} wpa2_ent_eap_state_t; + struct wifi_ssid { int len; uint8_t ssid[32]; }; +struct wps_scan_ie { + uint8_t *bssid; + uint8_t chan; + uint16_t capinfo; + uint8_t *ssid; + uint8_t *wpa; + uint8_t *rsn; + uint8_t *wps; +}; + +typedef struct { + int proto; + int pairwise_cipher; + int group_cipher; + int key_mgmt; + int capabilities; + size_t num_pmkid; + const u8 *pmkid; + int mgmt_group_cipher; +} wifi_wpa_ie_t; + +struct wpa_funcs { + bool (*wpa_sta_init)(void); + bool (*wpa_sta_deinit)(void); + void (*wpa_sta_connect)(uint8_t *bssid); + void (*wpa_sta_disconnected_cb)(uint8_t reason_code); + int (*wpa_sta_rx_eapol)(u8 *src_addr, u8 *buf, u32 len); + bool (*wpa_sta_in_4way_handshake)(void); + void *(*wpa_ap_init)(void); + bool (*wpa_ap_deinit)(void *data); + bool (*wpa_ap_join)(void **sm, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len); + bool (*wpa_ap_remove)(void *sm); + uint8_t *(*wpa_ap_get_wpa_ie)(uint8_t *len); + bool (*wpa_ap_rx_eapol)(void *hapd_data, void *sm, u8 *data, size_t data_len); + char *(*wpa_config_parse_string)(const char *value, size_t *len); + int (*wpa_parse_wpa_ie)(const u8 *wpa_ie, size_t wpa_ie_len, wifi_wpa_ie_t *data); + int (*wpa_config_bss)(u8 *bssid); + int (*wpa_michael_mic_failure)(u16 is_unicast); + uint8_t *(*wpa3_build_sae_msg)(uint8_t *bssid, uint32_t type, size_t *len); + int (*wpa3_parse_sae_msg)(uint8_t *buf, size_t len, uint32_t type, uint16_t status); +}; + +struct wpa2_funcs { + int (*wpa2_sm_rx_eapol)(u8 *src_addr, u8 *buf, u32 len, u8 *bssid); + int (*wpa2_start)(void); + int (*wpa2_init)(void); + void (*wpa2_deinit)(void); +}; + +struct wps_funcs { + bool (*wps_parse_scan_result)(struct wps_scan_ie *scan); + int (*wifi_station_wps_start)(void); + int (*wps_sm_rx_eapol)(u8 *src_addr, u8 *buf, u32 len); + int (*wps_start_pending)(void); +}; + +typedef esp_err_t (*wifi_wpa2_fn_t)(void *); +typedef struct { + wifi_wpa2_fn_t fn; + void *param; +} wifi_wpa2_param_t; + +#define IS_WPS_REGISTRAR(type) (((type)>WPS_TYPE_MAX)?(((type)WPS_TYPE_DISABLE)?(((type)finish_state = state; + esp_wifi_set_wpa2_ent_state_internal(state); +} + +static inline void wpa2_task_delete(void *arg) +{ + void *my_task_hdl = xTaskGetCurrentTaskHandle(); + int ret = ESP_OK; + + if (my_task_hdl == s_wpa2_task_hdl) { + wpa_printf(MSG_ERROR, "WPA2: should never call task delete api in wpa2 task context"); + return; + } + + ret = wpa2_post(SIG_WPA2_TASK_DEL, 0); + + if (ESP_OK != ret) { + wpa_printf(MSG_ERROR, "WPA2: failed to post task delete event, ret=%d", ret); + return; + } +} + +#define WPA_ADDR_LEN 6 +struct wpa2_rx_param { + uint8_t *bssid; + u8 sa[WPA_ADDR_LEN]; + u8 *buf; + int len; + STAILQ_ENTRY(wpa2_rx_param) bqentry; +}; +static STAILQ_HEAD(, wpa2_rx_param) s_wpa2_rxq; + +static void wpa2_rxq_init(void) +{ + DATA_MUTEX_TAKE(); + STAILQ_INIT(&s_wpa2_rxq); + DATA_MUTEX_GIVE(); +} + +static void wpa2_rxq_enqueue(struct wpa2_rx_param *param) +{ + DATA_MUTEX_TAKE(); + STAILQ_INSERT_TAIL(&s_wpa2_rxq,param, bqentry); + DATA_MUTEX_GIVE(); +} + +static struct wpa2_rx_param * wpa2_rxq_dequeue(void) +{ + struct wpa2_rx_param *param = NULL; + DATA_MUTEX_TAKE(); + if ((param = STAILQ_FIRST(&s_wpa2_rxq)) != NULL) { + STAILQ_REMOVE_HEAD(&s_wpa2_rxq, bqentry); + STAILQ_NEXT(param,bqentry) = NULL; + } + DATA_MUTEX_GIVE(); + return param; +} + +static void wpa2_rxq_deinit(void) +{ + struct wpa2_rx_param *param = NULL; + DATA_MUTEX_TAKE(); + while ((param = STAILQ_FIRST(&s_wpa2_rxq)) != NULL) { + STAILQ_REMOVE_HEAD(&s_wpa2_rxq, bqentry); + STAILQ_NEXT(param,bqentry) = NULL; + os_free(param->buf); + os_free(param); + } + DATA_MUTEX_GIVE(); +} + +void wpa2_task(void *pvParameters ) +{ + ETSEvent *e; + struct eap_sm *sm = gEapSm; + bool task_del = false; + + if (!sm) { + return; + } + + for (;;) { + if ( pdPASS == xQueueReceive(s_wpa2_queue, &e, portMAX_DELAY) ) { + if (e->sig < SIG_WPA2_MAX) { + DATA_MUTEX_TAKE(); + if(sm->wpa2_sig_cnt[e->sig]) { + sm->wpa2_sig_cnt[e->sig]--; + } else { + wpa_printf(MSG_ERROR, "wpa2_task: invalid sig cnt, sig=%d cnt=%d", e->sig, sm->wpa2_sig_cnt[e->sig]); + } + DATA_MUTEX_GIVE(); + } + switch (e->sig) { + case SIG_WPA2_TASK_DEL: + task_del = true; + break; + case SIG_WPA2_START: + wpa2_start_eapol_internal(); + break; + case SIG_WPA2_RX: { + struct wpa2_rx_param *param = NULL; + + while ((param = wpa2_rxq_dequeue()) != NULL){ + eap_sm_rx_eapol_internal(param->sa, param->buf, param->len, param->bssid); + os_free(param->buf); + os_free(param); + } + break; + } + default: + break; + } + os_free(e); + } + + if (task_del) { + break; + } else { + if (s_wifi_wpa2_sync_sem) { + wpa_printf(MSG_DEBUG, "WPA2: wifi->wpa2 api completed sig(%d)", e->sig); + xSemaphoreGive(s_wifi_wpa2_sync_sem); + } else { + wpa_printf(MSG_ERROR, "WPA2: null wifi->wpa2 sync sem"); + } + } + } + + wpa_printf(MSG_DEBUG, "WPA2: queue deleted"); + vQueueDelete(s_wpa2_queue); + wpa_printf(MSG_DEBUG, "WPA2: task deleted"); + s_wpa2_queue = NULL; + if (s_wifi_wpa2_sync_sem) { + wpa_printf(MSG_DEBUG, "WPA2: wifi->wpa2 api completed sig(%d)", e->sig); + xSemaphoreGive(s_wifi_wpa2_sync_sem); + } else { + wpa_printf(MSG_ERROR, "WPA2: null wifi->wpa2 sync sem"); + } + + /* At this point, we completed */ + vTaskDelete(NULL); +} + +int wpa2_post(uint32_t sig, uint32_t par) +{ + struct eap_sm *sm = gEapSm; + + if (!sm) { + return ESP_FAIL; + } + + DATA_MUTEX_TAKE(); + if (sm->wpa2_sig_cnt[sig]) { + DATA_MUTEX_GIVE(); + return ESP_OK; + } else { + ETSEvent *evt = (ETSEvent *)os_malloc(sizeof(ETSEvent)); + if (evt == NULL) { + wpa_printf(MSG_ERROR, "WPA2: E N M\n"); + DATA_MUTEX_GIVE(); + return ESP_FAIL; + } + sm->wpa2_sig_cnt[sig]++; + DATA_MUTEX_GIVE(); + evt->sig = sig; + evt->par = par; + if ( xQueueSend(s_wpa2_queue, &evt, 10 / portTICK_PERIOD_MS ) != pdPASS) { + wpa_printf(MSG_ERROR, "WPA2: Q S E"); + return ESP_FAIL; + } else { + if (s_wifi_wpa2_sync_sem) { + xSemaphoreTake(s_wifi_wpa2_sync_sem, portMAX_DELAY); + wpa_printf(MSG_DEBUG, "WPA2: wpa2 api return, sm->state(%d)", sm->finish_state); + } else { + wpa_printf(MSG_ERROR, "WPA2: null wifi->wpa2 sync sem"); + } + } + } + return ESP_OK; +} + +#endif /* USE_WPA2_TASK */ + +static void wpa2_sendto_wrapper(void *buffer, uint16_t len) +{ + esp_wifi_internal_tx(WIFI_IF_STA, buffer, len); +} + +static inline int wpa2_sm_ether_send(struct eap_sm *sm, const u8 *dest, u16 proto, + const u8 *data, size_t data_len) +{ + void *buffer = (void *)(data - sizeof(struct l2_ethhdr)); + struct l2_ethhdr *eth = NULL; + + if (!buffer) { + wpa_printf(MSG_ERROR, "wpa2: invalid data"); + return ESP_FAIL; + } else { + eth = (struct l2_ethhdr *)buffer; + memcpy(eth->h_dest, dest, ETH_ALEN); + memcpy(eth->h_source, sm->ownaddr, ETH_ALEN); + eth->h_proto = host_to_be16(proto); + wpa2_sendto_wrapper(buffer, sizeof(struct l2_ethhdr) + data_len); + } + + return ESP_OK; +} + +u8 *wpa2_sm_alloc_eapol(struct eap_sm *sm, u8 type, + const void *data, u16 data_len, + size_t *msg_len, void **data_pos) +{ + void *buffer; + struct ieee802_1x_hdr *hdr; + + *msg_len = sizeof(struct ieee802_1x_hdr) + data_len; + /* XXX: reserve l2_ethhdr is enough */ + buffer = os_malloc(*msg_len + sizeof(struct l2_ethhdr)); + + if (buffer == NULL) { + return NULL; + } + + hdr = (struct ieee802_1x_hdr *)((char *)buffer + sizeof(struct l2_ethhdr)); + hdr->version = 0x01; + hdr->type = type; + hdr->length = host_to_be16(data_len); + + if (data) { + memcpy(hdr + 1, data, data_len); + } else { + memset(hdr + 1, 0, data_len); + } + + if (data_pos) { + *data_pos = hdr + 1; + } + + return (u8 *) hdr; +} + + +void wpa2_sm_free_eapol(u8 *buffer) +{ + if (buffer != NULL) { + buffer = buffer - sizeof(struct l2_ethhdr); + os_free(buffer); + } + +} + +int eap_sm_send_eapol(struct eap_sm *sm, struct wpabuf *resp) +{ + size_t outlen; + int ret; + u8 *outbuf = NULL; + + u8 bssid[6]; + ret = esp_wifi_get_assoc_bssid_internal(bssid); + + if (ret != 0) { + wpa_printf(MSG_DEBUG, "bssid is empty \n"); + return WPA_ERR_INVALID_BSSID; + } + + outbuf = wpa2_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAP_PACKET, + wpabuf_head_u8(resp), wpabuf_len(resp), + &outlen, NULL); + if (!outbuf) { + return ESP_ERR_NO_MEM; + } + + ret = wpa2_sm_ether_send(sm, bssid, ETH_P_EAPOL, outbuf, outlen); + wpa2_sm_free_eapol(outbuf); + if (ret) { + return ESP_FAIL; + } + + return ESP_OK; +} + +int eap_sm_process_request(struct eap_sm *sm, struct wpabuf *reqData) +{ + size_t plen; + u32 reqVendor, reqVendorMethod; + u8 type, *pos; + struct eap_hdr *ehdr; + const struct eap_method *m = NULL; + struct wpabuf *resp = NULL; + struct eap_method_ret m_res; + int ret = 0; + + if (reqData == NULL || wpabuf_len(reqData) < sizeof(*ehdr)) { + return ESP_ERR_INVALID_ARG; + } + + ehdr = (struct eap_hdr *)wpabuf_head(reqData); + plen = be_to_host16(ehdr->length); + if (plen > wpabuf_len(reqData)) { + return ESP_FAIL; + } + + if (ehdr->identifier == sm->current_identifier) { + /*Retransmit*/ + resp = sm->lastRespData; + goto send_resp; + } + + sm->current_identifier = ehdr->identifier; + + pos = (u8 *)(ehdr + 1); + type = *pos++; + if (type == EAP_TYPE_IDENTITY) { + resp = (struct wpabuf *)eap_sm_build_identity_resp(sm, ehdr->identifier, 0); + goto send_resp; + } else if (type == EAP_TYPE_NOTIFICATION) { + /*Ignore*/ + goto out; + } else if (type == EAP_TYPE_EXPANDED) { + if (plen < sizeof(*ehdr) + 8) { + return ESP_FAIL; + } + reqVendor = WPA_GET_BE24(pos); + pos += 3; + reqVendorMethod = WPA_GET_BE32(pos); + } else { + reqVendor = EAP_VENDOR_IETF; + reqVendorMethod = type; + } + + if (sm->m && sm->m->process && sm->eap_method_priv && + reqVendor == sm->m->vendor && + reqVendorMethod == sm->m->method) { + resp = sm->m->process(sm, sm->eap_method_priv, + &m_res, reqData); + } else { + m = eap_peer_get_eap_method(reqVendor, reqVendorMethod); + if (m == NULL) { + goto build_nak; + } + if (sm->m) { + eap_deinit_prev_method(sm, "GET_METHOD"); + } + sm->m = m; + sm->eap_method_priv = sm->m->init(sm); + if (sm->eap_method_priv == NULL) { + wpa_printf(MSG_ERROR, "Method private structure allocated failure\n"); + sm->m = NULL; + goto build_nak; + } + + if (sm->m->process) { + resp = sm->m->process(sm, sm->eap_method_priv, &m_res, reqData); + } + } + + if (sm->m->isKeyAvailable && sm->m->getKey && + sm->m->isKeyAvailable(sm, sm->eap_method_priv)) { + if (sm->eapKeyData) { + os_free(sm->eapKeyData); + } + sm->eapKeyData = sm->m->getKey(sm, sm->eap_method_priv, + &sm->eapKeyDataLen); + } + goto send_resp; + +build_nak: + resp = (struct wpabuf *)eap_sm_build_nak(sm, type, ehdr->identifier); + if (resp == NULL) { + return ESP_FAIL; + } + ret = ESP_FAIL; + +send_resp: + if (resp == NULL) { + wpa_printf(MSG_ERROR, "Response build fail, return."); + return ESP_FAIL; + } + ret = eap_sm_send_eapol(sm, resp); + if (ret == ESP_OK) { + if (resp != sm->lastRespData) { + wpabuf_free(sm->lastRespData); + sm->lastRespData = resp; + } + } else { + wpabuf_free(sm->lastRespData); + sm->lastRespData = NULL; + wpabuf_free(resp); + resp = NULL; + + if (ret == WPA_ERR_INVALID_BSSID) { + ret = WPA2_ENT_EAP_STATE_FAIL; + wpa2_set_eap_state(WPA2_ENT_EAP_STATE_FAIL); + } + } +out: + return ret; +} + +static int eap_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len, uint8_t *bssid) +{ + struct eap_sm *sm = gEapSm; + + if (!sm) { + return ESP_FAIL; + } +#ifdef USE_WPA2_TASK + { + struct wpa2_rx_param *param = (struct wpa2_rx_param *)os_zalloc(sizeof(struct wpa2_rx_param)); /* free in task */ + + if (!param) { + return ESP_ERR_NO_MEM; + } + + param->buf = (u8 *)os_zalloc(len); /* free in task */ + if (!param->buf) { + os_free(param); + return ESP_ERR_NO_MEM; + } + param->bssid = bssid; + memcpy(param->buf, buf, len); + param->len = len; + memcpy(param->sa, src_addr, WPA_ADDR_LEN); + + wpa2_rxq_enqueue(param); + return wpa2_post(SIG_WPA2_RX, 0); + } +#else + + return eap_sm_rx_eapol_internal(src_addr, buf, len, bssid); +#endif +} + +static int wpa2_ent_rx_eapol(u8 *src_addr, u8 *buf, u32 len, uint8_t *bssid) +{ + struct ieee802_1x_hdr *hdr; + int ret = ESP_OK; + + hdr = (struct ieee802_1x_hdr *) buf; + + switch (hdr->type) { + case IEEE802_1X_TYPE_EAPOL_START: + case IEEE802_1X_TYPE_EAP_PACKET: + case IEEE802_1X_TYPE_EAPOL_LOGOFF: + ret = eap_sm_rx_eapol(src_addr, buf, len, bssid); + break; + case IEEE802_1X_TYPE_EAPOL_KEY: + ret = wpa_sm_rx_eapol(src_addr, buf, len); + break; + default: + wpa_printf(MSG_ERROR, "Unknown EAPOL packet type - %d\n", hdr->type); + break; + } + + return ret; +} + +static int eap_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len, uint8_t *bssid) +{ + struct eap_sm *sm = gEapSm; + u32 plen, data_len; + struct ieee802_1x_hdr *hdr; + struct eap_hdr *ehdr; + struct wpabuf *req = NULL; + u8 *tmp; + int ret = ESP_FAIL; + + if (!sm) { + return ESP_FAIL; + } + + if (len < sizeof(*hdr) + sizeof(*ehdr)) { +#ifdef DEBUG_PRINT + wpa_printf(MSG_DEBUG, "WPA: EAPOL frame too short to be a WPA " + "EAPOL-Key (len %lu, expecting at least %lu)", + (unsigned long) len, + (unsigned long) sizeof(*hdr) + sizeof(*ehdr)); +#endif + return ESP_FAIL; + } + + tmp = buf; + + hdr = (struct ieee802_1x_hdr *) tmp; + ehdr = (struct eap_hdr *) (hdr + 1); + plen = be_to_host16(hdr->length); + data_len = plen + sizeof(*hdr); + +#ifdef DEBUG_PRINT + wpa_printf(MSG_DEBUG, "IEEE 802.1X RX: version=%d type=%d length=%d\n", + hdr->version, hdr->type, plen); +#endif + if (hdr->version < EAPOL_VERSION) { + /* TODO: backwards compatibility */ + } + if (hdr->type != IEEE802_1X_TYPE_EAP_PACKET) { +#ifdef DEBUG_PRINT + wpa_printf(MSG_DEBUG, "WPA2: EAP frame (type %u) discarded, " + "not a EAP PACKET frame", hdr->type); +#endif + ret = -2; + goto _out; + } + if (plen > len - sizeof(*hdr) || plen < sizeof(*ehdr)) { +#ifdef DEBUG_PRINT + wpa_printf(MSG_DEBUG, "WPA2: EAPOL frame payload size %lu " + "invalid (frame size %lu)", + (unsigned long) plen, (unsigned long) len); +#endif + ret = -2; + goto _out; + } + + wpa_hexdump(MSG_MSGDUMP, "WPA2: RX EAPOL-EAP PACKET", tmp, len); + + if (data_len < len) { +#ifdef DEBUG_PRINT + wpa_printf(MSG_DEBUG, "WPA: ignoring %lu bytes after the IEEE " + "802.1X data\n", (unsigned long) len - data_len); +#endif + } + +#ifdef EAP_PEER_METHOD + switch (ehdr->code) { + case EAP_CODE_REQUEST: + /* Handle EAP-reauthentication case */ + if (sm->finish_state == WPA2_ENT_EAP_STATE_SUCCESS) { + wpa_printf(MSG_INFO, ">>>>>wpa2 EAP Re-authentication in progress\n"); + wpa2_set_eap_state(WPA2_ENT_EAP_STATE_IN_PROGRESS); + } + + req = wpabuf_alloc_copy((u8 *)ehdr, len - sizeof(*hdr)); + ret = eap_sm_process_request(sm, req); + break; + case EAP_CODE_RESPONSE: + /*Ignore*/ + break; + case EAP_CODE_SUCCESS: + if (sm->eapKeyData) { + wpa_set_pmk(sm->eapKeyData, NULL, false); + os_free(sm->eapKeyData); + sm->eapKeyData = NULL; + wpa_printf(MSG_INFO, ">>>>>wpa2 FINISH\n"); + ret = WPA2_ENT_EAP_STATE_SUCCESS; + wpa2_set_eap_state(WPA2_ENT_EAP_STATE_SUCCESS); + eap_deinit_prev_method(sm, "EAP Success"); + } else { + wpa_printf(MSG_INFO, ">>>>>wpa2 FAILED, receive EAP_SUCCESS but pmk is empty, potential attack!\n"); + ret = WPA2_ENT_EAP_STATE_FAIL; + wpa2_set_eap_state(WPA2_ENT_EAP_STATE_FAIL); + } + break; + case EAP_CODE_FAILURE: + wpa_printf(MSG_INFO, ">>>>>wpa2 FAILED\n"); + ret = WPA2_ENT_EAP_STATE_FAIL; + wpa2_set_eap_state(WPA2_ENT_EAP_STATE_FAIL); + break; + } +_out: + wpabuf_free(req); +#endif + return ret; +} + +static int wpa2_start_eapol(void) +{ +#ifdef USE_WPA2_TASK + return wpa2_post(SIG_WPA2_START, 0); +#else + return wpa2_start_eapol_internal(); +#endif +} + +static int wpa2_start_eapol_internal(void) +{ + struct eap_sm *sm = gEapSm; + int ret = 0; + u8 bssid[6]; + u8 *buf; + size_t len; + + if (!sm) { + return ESP_FAIL; + } + + if (wpa_sta_cur_pmksa_matches_akm()) { + wpa_printf(MSG_DEBUG, + "RSN: PMKSA caching - do not send EAPOL-Start"); + return ESP_FAIL; + } + + ret = esp_wifi_get_assoc_bssid_internal(bssid); + if (ret != 0) { + wpa_printf(MSG_ERROR, "bssid is empty!"); + return WPA_ERR_INVALID_BSSID; + } + + buf = wpa2_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START, (u8 *)"", 0, &len, NULL); + if (!buf) { + return ESP_FAIL; + } + + wpa2_set_eap_state(WPA2_ENT_EAP_STATE_IN_PROGRESS); + wpa2_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len); + wpa2_sm_free_eapol(buf); + return ESP_OK; +} + +/** + * eap_peer_sm_init - Allocate and initialize EAP peer state machine + * @eapol_ctx: Context data to be used with eapol_cb calls + * @eapol_cb: Pointer to EAPOL callback functions + * @msg_ctx: Context data for wpa_msg() calls + * @conf: EAP configuration + * Returns: Pointer to the allocated EAP state machine or %NULL on failure + * + * This function allocates and initializes an EAP state machine. In addition, + * this initializes TLS library for the new EAP state machine. eapol_cb pointer + * will be in use until eap_peer_sm_deinit() is used to deinitialize this EAP + * state machine. Consequently, the caller must make sure that this data + * structure remains alive while the EAP state machine is active. + */ +static int eap_peer_sm_init(void) +{ + int ret = 0; + struct eap_sm *sm; + + if (gEapSm) { + wpa_printf(MSG_ERROR, "WPA2: wpa2 sm not null, deinit it"); + eap_peer_sm_deinit(); + } + + sm = (struct eap_sm *)os_zalloc(sizeof(*sm)); + if (sm == NULL) { + return ESP_ERR_NO_MEM; + } + + s_wpa2_data_lock = xSemaphoreCreateRecursiveMutex(); + if (!s_wpa2_data_lock) { + wpa_printf(MSG_ERROR, "wpa2 eap_peer_sm_init: failed to alloc data lock"); // NOLINT(clang-analyzer-unix.Malloc) + return ESP_ERR_NO_MEM; + } + + wpa2_set_eap_state(WPA2_ENT_EAP_STATE_NOT_START); + sm->current_identifier = 0xff; + esp_wifi_get_macaddr_internal(WIFI_IF_STA, sm->ownaddr); + ret = eap_peer_blob_init(sm); + if (ret) { + wpa_printf(MSG_ERROR, "eap_peer_blob_init failed\n"); + os_free(sm); + vSemaphoreDelete(s_wpa2_data_lock); + return ESP_FAIL; + } + + ret = eap_peer_config_init(sm, g_wpa_private_key_passwd, g_wpa_private_key_passwd_len); + if (ret) { + wpa_printf(MSG_ERROR, "eap_peer_config_init failed\n"); + eap_peer_blob_deinit(sm); + os_free(sm); + vSemaphoreDelete(s_wpa2_data_lock); + return ESP_FAIL; + } + + sm->ssl_ctx = tls_init(); + if (sm->ssl_ctx == NULL) { + wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS " + "context."); + eap_peer_blob_deinit(sm); + eap_peer_config_deinit(sm); + os_free(sm); + vSemaphoreDelete(s_wpa2_data_lock); + return ESP_FAIL; + } + + wpa2_rxq_init(); + + gEapSm = sm; +#ifdef USE_WPA2_TASK + s_wpa2_queue = xQueueCreate(SIG_WPA2_MAX, sizeof( void * ) ); + xTaskCreate(wpa2_task, "wpa2T", WPA2_TASK_STACK_SIZE, NULL, 2, &s_wpa2_task_hdl); + s_wifi_wpa2_sync_sem = xSemaphoreCreateCounting(1, 0); + if (!s_wifi_wpa2_sync_sem) { + vQueueDelete(s_wpa2_queue); + s_wpa2_queue = NULL; + eap_peer_blob_deinit(sm); + eap_peer_config_deinit(sm); + os_free(sm); + vSemaphoreDelete(s_wpa2_data_lock); + wpa_printf(MSG_ERROR, "WPA2: failed create wifi wpa2 task sync sem"); + return ESP_FAIL; + } + + wpa_printf(MSG_INFO, "wpa2_task prio:%d, stack:%d\n", 2, WPA2_TASK_STACK_SIZE); + +#endif + return ESP_OK; +} + +/** + * eap_peer_sm_deinit - Deinitialize and free an EAP peer state machine + * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() + * + * This function deinitializes EAP state machine and frees all allocated + * resources. + */ +static void eap_peer_sm_deinit(void) +{ + struct eap_sm *sm = gEapSm; + + if (sm == NULL) { + return; + } + + eap_peer_config_deinit(sm); + eap_peer_blob_deinit(sm); + eap_deinit_prev_method(sm, "EAP deinit"); + eap_sm_abort(sm); + tls_deinit(sm->ssl_ctx); +#ifdef USE_WPA2_TASK + wpa2_task_delete(0); +#endif + + if (STAILQ_FIRST((&s_wpa2_rxq)) != NULL) { + wpa2_rxq_deinit(); + } + + if (s_wifi_wpa2_sync_sem) { + vSemaphoreDelete(s_wifi_wpa2_sync_sem); + } + s_wifi_wpa2_sync_sem = NULL; + + if (s_wpa2_data_lock) { + vSemaphoreDelete(s_wpa2_data_lock); + s_wpa2_data_lock = NULL; + wpa_printf(MSG_DEBUG, "wpa2 eap_peer_sm_deinit: free data lock"); + } + + os_free(sm); + gEapSm = NULL; +} + +esp_err_t esp_wifi_sta_wpa2_ent_enable_fn(void *arg) +{ + struct wpa2_funcs *wpa2_cb; + + wpa_printf(MSG_INFO, "WPA2 ENTERPRISE VERSION: [%s] enable\n", + WPA2_VERSION); + + wpa2_cb = (struct wpa2_funcs *)os_zalloc(sizeof(struct wpa2_funcs)); + if (wpa2_cb == NULL) { + wpa_printf(MSG_ERROR, "WPA2: no mem for wpa2 cb\n"); + return ESP_ERR_NO_MEM; + } + + wpa2_cb->wpa2_sm_rx_eapol = wpa2_ent_rx_eapol; + wpa2_cb->wpa2_start = wpa2_start_eapol; + wpa2_cb->wpa2_init = eap_peer_sm_init; + wpa2_cb->wpa2_deinit = eap_peer_sm_deinit; + + esp_wifi_register_wpa2_cb_internal(wpa2_cb); + + wpa_printf(MSG_DEBUG, "WPA2 ENTERPRISE CRYPTO INIT.\r\n"); + +#ifdef EAP_PEER_METHOD + if (eap_peer_register_methods()) { + wpa_printf(MSG_ERROR, "Register EAP Peer methods Failure\n"); + } +#endif + return ESP_OK; +} + +esp_err_t esp_wifi_sta_wpa2_ent_enable(void) +{ + wifi_wpa2_param_t param; + esp_err_t ret; + + wpa2_api_lock(); + + if (wpa2_is_enabled()) { + wpa_printf(MSG_INFO, "WPA2: already enabled"); + wpa2_api_unlock(); + return ESP_OK; + } + + param.fn = (wifi_wpa2_fn_t)esp_wifi_sta_wpa2_ent_enable_fn; + param.param = NULL; + + ret = esp_wifi_sta_wpa2_ent_enable_internal(¶m); + + if (ESP_OK == ret) { + wpa2_set_state(WPA2_STATE_ENABLED); + } else { + wpa_printf(MSG_ERROR, "failed to enable wpa2 ret=%d", ret); + } + + wpa2_api_unlock(); + + return ret; +} + +esp_err_t esp_wifi_sta_wpa2_ent_disable_fn(void *param) +{ + wpa_printf(MSG_INFO, "WPA2 ENTERPRISE VERSION: [%s] disable\n", WPA2_VERSION); + esp_wifi_unregister_wpa2_cb_internal(); + + if (gEapSm) { + eap_peer_sm_deinit(); + } + +#ifdef USE_WPA2_TASK +#endif + +#ifdef EAP_PEER_METHOD + eap_peer_unregister_methods(); +#endif + + return ESP_OK; +} + +esp_err_t esp_wifi_sta_wpa2_ent_disable(void) +{ + wifi_wpa2_param_t param; + esp_err_t ret; + + wpa2_api_lock(); + + if (wpa2_is_disabled()) { + wpa_printf(MSG_INFO, "WPA2: already disabled"); + wpa2_api_unlock(); + return ESP_OK; + } + + param.fn = (wifi_wpa2_fn_t)esp_wifi_sta_wpa2_ent_disable_fn; + param.param = 0; + ret = esp_wifi_sta_wpa2_ent_disable_internal(¶m); + + if (ESP_OK == ret) { + wpa2_set_state(WPA2_STATE_DISABLED); + } else { + wpa_printf(MSG_ERROR, "failed to disable wpa2 ret=%d", ret); + } + + wpa2_api_unlock(); + + return ret; +} 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) { @@ -71,7 +977,7 @@ esp_err_t esp_wifi_sta_wpa2_ent_set_cert_key(const unsigned char *client_cert, i void esp_wifi_sta_wpa2_ent_clear_cert_key(void) { - wifi_unregister_wpa2_cb(); + esp_wifi_unregister_wpa2_cb_internal(); g_wpa_client_cert = NULL; g_wpa_client_cert_len = 0; diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_wpa3.c b/components/wpa_supplicant/src/esp_supplicant/esp_wpa3.c index 3332810f..3a106b5c 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_wpa3.c +++ b/components/wpa_supplicant/src/esp_supplicant/esp_wpa3.c @@ -32,7 +32,7 @@ static esp_err_t wpa3_build_sae_commit(u8 *bssid) u8 own_addr[ETH_ALEN]; const u8 *pw; - if (wpa_sta_is_cur_pmksa_set()) { + if (wpa_sta_cur_pmksa_matches_akm()) { wpa_printf(MSG_INFO, "wpa3: Skip SAE and use cached PMK instead"); return ESP_FAIL; } @@ -130,7 +130,7 @@ void esp_wpa3_free_sae_data(void) sae_clear_data(&g_sae_data); } -u8 *wpa3_build_sae_msg(u8 *bssid, u32 sae_msg_type, u32 *sae_msg_len) +static u8 *wpa3_build_sae_msg(u8 *bssid, u32 sae_msg_type, u32 *sae_msg_len) { u8 *buf = NULL; @@ -201,12 +201,11 @@ static int wpa3_parse_sae_confirm(u8 *buf, u32 len) g_sae_data.state = SAE_ACCEPTED; wpa_set_pmk(g_sae_data.pmk, g_sae_data.pmkid, true); - memcpy(esp_wifi_sta_get_ap_info_prof_pmk_internal(), g_sae_data.pmk, PMK_LEN); return ESP_OK; } -int wpa3_parse_sae_msg(u8 *buf, u32 len, u32 sae_msg_type, u16 status) +static int wpa3_parse_sae_msg(u8 *buf, u32 len, u32 sae_msg_type, u16 status) { int ret = ESP_OK; @@ -226,15 +225,11 @@ int wpa3_parse_sae_msg(u8 *buf, u32 len, u32 sae_msg_type, u16 status) return ret; } -#else -u8 *wpa3_build_sae_msg(u8 *bssid, u32 sae_msg_type, u32 *sae_msg_len) -{ - return NULL; -} -int wpa3_parse_sae_msg(u8 *buf, u32 len, u32 sae_msg_type, u16 status) +void esp_wifi_register_wpa3_cb(struct wpa_funcs *wpa_cb) { - return ESP_FAIL; + wpa_cb->wpa3_build_sae_msg = wpa3_build_sae_msg; + wpa_cb->wpa3_parse_sae_msg = wpa3_parse_sae_msg; } #endif /* CONFIG_WPA3_SAE */ diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_wpa3_i.h b/components/wpa_supplicant/src/esp_supplicant/esp_wpa3_i.h index 694fc422..93223040 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_wpa3_i.h +++ b/components/wpa_supplicant/src/esp_supplicant/esp_wpa3_i.h @@ -20,9 +20,16 @@ #ifdef CONFIG_WPA3_SAE +void esp_wifi_register_wpa3_cb(struct wpa_funcs *wpa_cb); +void esp_wpa3_free_sae_data(void); #else /* CONFIG_WPA3_SAE */ +static inline void esp_wifi_register_wpa3_cb(struct wpa_funcs *wpa_cb) +{ + wpa_cb->wpa3_build_sae_msg = NULL; + wpa_cb->wpa3_parse_sae_msg = NULL; +} #endif /* CONFIG_WPA3_SAE */ #endif /* ESP_WPA3_H */ diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c b/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c index acfa3209..4fa9d1cc 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c +++ b/components/wpa_supplicant/src/esp_supplicant/esp_wpa_main.c @@ -19,20 +19,21 @@ #include "common/eapol_common.h" #include "common/ieee802_11_defs.h" #include "rsn_supp/wpa_ie.h" +#include "ap/wpa_auth.h" +#include "ap/wpa_auth_i.h" +#include "ap/ap_config.h" +#include "ap/hostapd.h" +#include "esp_wpas_glue.h" +#include "esp_hostap.h" + +#include "esp_system.h" #include "crypto/crypto.h" #include "crypto/sha1.h" #include "crypto/aes_wrap.h" -#include "esp_supplicant/esp_wpas_glue.h" #include "esp_wifi_driver.h" -#define LOCAL static - -extern struct ieee80211_cipher tkip; -extern struct ieee80211_cipher ccmp; -extern struct ieee80211_cipher wep; - -extern bool dhcpc_flag; - +#include "esp_private/wifi.h" +#include "esp_wpa3_i.h" void wpa_install_key(enum wpa_alg alg, u8 *addr, int key_idx, int set_tx, u8 *seq, size_t seq_len, u8 *key, size_t key_len, int key_entry_valid) @@ -58,48 +59,12 @@ int wpa_get_key(uint8_t *ifx, int *alg, u8 *addr, int *key_idx, * been completed successfully since WPA-PSK does not use EAP state machine. */ -#include "esp_aio.h" -#define EP_OFFSET 36 -int ieee80211_output_pbuf(esp_aio_t *aio); /* fix buf for tx for now */ #define WPA_TX_MSG_BUFF_MAXLEN 200 -LOCAL int wpa_send_cb(esp_aio_t* aio) +void wpa_sendto_wrapper(void *buffer, u16 len) { - char* pb = (char*)aio->arg; - - os_free(pb); - - return 0; -} - -void wpa_sendto_wrapper(void* dataptr, u16 datalen) -{ -#ifndef IOT_SIP_MODE - esp_aio_t aio; - - aio.arg = dataptr - EP_OFFSET; - aio.cb = wpa_send_cb; - aio.fd = 0; - aio.pbuf = (char *)dataptr; - aio.len = datalen; - aio.ret = 0; - - if (ieee80211_output_pbuf(&aio) != 0) { - os_free(dataptr - EP_OFFSET); - } - -#else - esf_buf* eb = NULL; - uint8_t* frm; - - eb = ieee80211_getmgtframe(&frm, sizeof(struct ieee80211_frame), WPA_TX_MSG_BUFF_MAXLEN); - os_memcpy(frm, msg, msg_len); -// eb->hdr_len = sizeof(struct ieee80211_frame); - eb->data_len = msg_len; - EBUF_START(eb) = frm; - ieee80211_output_pbuf(ic->ic_if0_conn, eb); -#endif + esp_wifi_internal_tx(0, buffer, len); } void wpa_deauthenticate(u8 reason_code) @@ -118,19 +83,25 @@ void wpa_config_profile(void) } } -void wpa_config_bss(uint8_t *bssid) +int wpa_config_bss(uint8_t *bssid) { - u8 mac[6]; + int ret = 0; struct wifi_ssid *ssid = esp_wifi_sta_get_prof_ssid_internal(); - esp_wifi_get_mac(WIFI_IF_STA, mac); + u8 mac[6]; - wpa_set_bss((char *)mac, (char *)bssid, esp_wifi_sta_get_pairwise_cipher_internal(), esp_wifi_sta_get_group_cipher_internal(), + esp_wifi_get_macaddr_internal(0, mac); + ret = wpa_set_bss((char *)mac, (char *)bssid, esp_wifi_sta_get_pairwise_cipher_internal(), esp_wifi_sta_get_group_cipher_internal(), (char *)esp_wifi_sta_get_prof_password_internal(), ssid->ssid, ssid->len); + return ret; } void wpa_config_assoc_ie(u8 proto, u8 *assoc_buf, u32 assoc_wpa_ie_len) { - esp_wifi_set_appie_internal(proto, assoc_buf, assoc_wpa_ie_len, 0); + if (proto == BIT(0)) { + esp_wifi_set_appie_internal(WIFI_APPIE_WPA, assoc_buf, assoc_wpa_ie_len, 1); + } else { + esp_wifi_set_appie_internal(WIFI_APPIE_RSN, assoc_buf, assoc_wpa_ie_len, 1); + } } void wpa_neg_complete(void) @@ -138,20 +109,130 @@ void wpa_neg_complete(void) esp_wifi_auth_done_internal(); } -void wpa_sta_init() +bool wpa_attach(void) { - wpa_register(NULL, wpa_sendto_wrapper, + bool ret = true; + ret = wpa_sm_init(NULL, wpa_sendto_wrapper, wpa_config_assoc_ie, wpa_install_key, wpa_get_key, wpa_deauthenticate, wpa_neg_complete); + if(ret) { + ret = (esp_wifi_register_tx_cb_internal(eapol_txcb, WIFI_TXCB_EAPOL_ID) == ESP_OK); + } + return ret; } -void wpa_sta_deinit(void) +uint8_t *wpa_ap_get_wpa_ie(uint8_t *ie_len) +{ + struct hostapd_data *hapd = (struct hostapd_data *)esp_wifi_get_hostap_private_internal(); + + if (!hapd || !hapd->wpa_auth || !hapd->wpa_auth->wpa_ie) { + return NULL; + } + + *ie_len = hapd->wpa_auth->wpa_ie_len; + return hapd->wpa_auth->wpa_ie; +} + +bool wpa_ap_rx_eapol(void *hapd_data, void *sm_data, u8 *data, size_t data_len) +{ + struct hostapd_data *hapd = (struct hostapd_data *)hapd_data; + struct wpa_state_machine *sm = (struct wpa_state_machine *)sm_data; + + if (!hapd || !sm) { + return false; + } + + wpa_receive(hapd->wpa_auth, sm, data, data_len); + + return true; +} + +bool wpa_deattach(void) { wpa_sm_deinit(); + return true; } void wpa_sta_connect(uint8_t *bssid) { + int ret = 0; wpa_config_profile(); - wpa_config_bss(bssid); + ret = wpa_config_bss(bssid); + WPA_ASSERT(ret == 0); } +int wpa_parse_wpa_ie_wrapper(const u8 *wpa_ie, size_t wpa_ie_len, wifi_wpa_ie_t *data) +{ + struct wpa_ie_data ie; + int ret = 0; + + ret = wpa_parse_wpa_ie(wpa_ie, wpa_ie_len, &ie); + data->proto = ie.proto; + data->pairwise_cipher = cipher_type_map_supp_to_public(ie.pairwise_cipher); + data->group_cipher = cipher_type_map_supp_to_public(ie.group_cipher); + data->key_mgmt = ie.key_mgmt; + data->capabilities = ie.capabilities; + data->pmkid = ie.pmkid; + data->mgmt_group_cipher = cipher_type_map_supp_to_public(ie.mgmt_group_cipher); + + return ret; +} + +static void wpa_sta_disconnected_cb(uint8_t reason_code) +{ + switch (reason_code) { + case WIFI_REASON_UNSPECIFIED: + case WIFI_REASON_AUTH_EXPIRE: + case WIFI_REASON_NOT_AUTHED: + case WIFI_REASON_NOT_ASSOCED: + case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: + case WIFI_REASON_INVALID_PMKID: + case WIFI_REASON_AUTH_FAIL: + case WIFI_REASON_ASSOC_FAIL: + case WIFI_REASON_CONNECTION_FAIL: + case WIFI_REASON_HANDSHAKE_TIMEOUT: + esp_wpa3_free_sae_data(); + wpa_sta_clear_curr_pmksa(); + break; + default: + break; + } +} + +int esp_supplicant_init(void) +{ + struct wpa_funcs *wpa_cb; + + wpa_cb = (struct wpa_funcs *)os_malloc(sizeof(struct wpa_funcs)); + if (!wpa_cb) { + return ESP_ERR_NO_MEM; + } + + wpa_cb->wpa_sta_init = wpa_attach; + wpa_cb->wpa_sta_deinit = wpa_deattach; + wpa_cb->wpa_sta_rx_eapol = wpa_sm_rx_eapol; + wpa_cb->wpa_sta_connect = wpa_sta_connect; + wpa_cb->wpa_sta_disconnected_cb = wpa_sta_disconnected_cb; + wpa_cb->wpa_sta_in_4way_handshake = wpa_sta_in_4way_handshake; + + wpa_cb->wpa_ap_join = wpa_ap_join; + wpa_cb->wpa_ap_remove = wpa_ap_remove; + wpa_cb->wpa_ap_get_wpa_ie = wpa_ap_get_wpa_ie; + wpa_cb->wpa_ap_rx_eapol = wpa_ap_rx_eapol; + wpa_cb->wpa_ap_init = hostap_init; + wpa_cb->wpa_ap_deinit = hostap_deinit; + + wpa_cb->wpa_config_parse_string = wpa_config_parse_string; + wpa_cb->wpa_parse_wpa_ie = wpa_parse_wpa_ie_wrapper; + wpa_cb->wpa_config_bss = NULL;//wpa_config_bss; + wpa_cb->wpa_michael_mic_failure = wpa_michael_mic_failure; + esp_wifi_register_wpa3_cb(wpa_cb); + + esp_wifi_register_wpa_cb_internal(wpa_cb); + + return ESP_OK; +} + +int esp_supplicant_deinit(void) +{ + return esp_wifi_unregister_wpa_cb_internal(); +} diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_wpas_glue.c b/components/wpa_supplicant/src/esp_supplicant/esp_wpas_glue.c index 5a03d3e7..1e3fc424 100644 --- a/components/wpa_supplicant/src/esp_supplicant/esp_wpas_glue.c +++ b/components/wpa_supplicant/src/esp_supplicant/esp_wpas_glue.c @@ -19,10 +19,6 @@ #include "common/eapol_common.h" #include "rsn_supp/wpa.h" #include "rsn_supp/pmksa_cache.h" -#define EP_OFFSET 36 - -#define wpa_malloc_dram(s) heap_caps_malloc(s, MALLOC_CAP_8BIT) -#define wpa_calloc_dram(n, s) heap_caps_calloc(n, s, MALLOC_CAP_8BIT) u8 *wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type, const void *data, u16 data_len, @@ -33,14 +29,12 @@ u8 *wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type, *msg_len = sizeof(struct ieee802_1x_hdr) + data_len; - buffer = wpa_malloc_dram(*msg_len + sizeof(struct l2_ethhdr) + EP_OFFSET); + buffer = os_malloc(*msg_len + sizeof(struct l2_ethhdr)); if (buffer == NULL) { return NULL; } - buffer += EP_OFFSET; - /* XXX: reserve l2_ethhdr is enough */ hdr = (struct ieee802_1x_hdr *)((char *)buffer + sizeof(struct l2_ethhdr)); @@ -63,8 +57,8 @@ u8 *wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type, void wpa_sm_free_eapol(u8 *buffer) { - // buffer = buffer - sizeof(struct l2_ethhdr) - EP_OFFSET; - // os_free(buffer); + buffer = buffer - sizeof(struct l2_ethhdr); + os_free(buffer); } void wpa_sm_deauthenticate(struct wpa_sm *sm, u8 reason_code) diff --git a/components/wpa_supplicant/src/esp_supplicant/esp_wps.c b/components/wpa_supplicant/src/esp_supplicant/esp_wps.c new file mode 100755 index 00000000..6190e4c1 --- /dev/null +++ b/components/wpa_supplicant/src/esp_supplicant/esp_wps.c @@ -0,0 +1,2196 @@ +// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "utils/includes.h" +#include "rsn_supp/wpa.h" +#include "utils/common.h" +#include "common/eapol_common.h" +#include "utils/wpa_debug.h" +#include "common/ieee802_11_defs.h" +#include "crypto/dh_group5.h" +#include "wps/wps_i.h" +#include "wps/wps_dev_attr.h" +#include "eap_peer/eap_defs.h" +#include "eap_peer/eap_common.h" +#include "esp_wifi_driver.h" +#include "esp_event.h" +#include "esp_wifi.h" +#include "esp_err.h" +#include "esp_private/wifi.h" + +#define API_MUTEX_TAKE() do {\ + if (!s_wps_api_lock) {\ + s_wps_api_lock = xSemaphoreCreateRecursiveMutex();\ + if (!s_wps_api_lock) {\ + wpa_printf(MSG_ERROR, "wps api lock create failed");\ + return ESP_ERR_NO_MEM;\ + }\ + }\ + xSemaphoreTakeRecursive(s_wps_api_lock, portMAX_DELAY);\ +} while(0) + +#define API_MUTEX_GIVE() xSemaphoreGiveRecursive(s_wps_api_lock) +#define DATA_MUTEX_TAKE() xSemaphoreTakeRecursive(s_wps_data_lock, portMAX_DELAY) +#define DATA_MUTEX_GIVE() xSemaphoreGiveRecursive(s_wps_data_lock) + +#define WPS_ADDR_LEN 6 +#ifdef USE_WPS_TASK +struct wps_rx_param { + u8 sa[WPS_ADDR_LEN]; + u8 *buf; + int len; + STAILQ_ENTRY(wps_rx_param) bqentry; +}; +static STAILQ_HEAD(,wps_rx_param) s_wps_rxq; + +typedef struct { + void *arg; + int ret; /* return value */ +} wps_ioctl_param_t; + +static TaskHandle_t s_wps_task_hdl = NULL; +static void *s_wps_queue = NULL; +static void *s_wps_api_lock = NULL; /* Used in WPS public API only, never be freed */ +static void *s_wps_api_sem = NULL; /* Sync semaphore used between WPS publi API caller task and WPS task */ +static void *s_wps_data_lock = NULL; +static void *s_wps_task_create_sem = NULL; +static bool s_wps_enabled = false; +static uint8_t s_wps_sig_cnt[SIG_WPS_NUM] = {0}; + +#endif + +void wifi_wps_scan_done(void *arg, STATUS status); +void wifi_wps_scan(void); +int wifi_station_wps_start(void); +int wps_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len); +void wifi_wps_start_internal(void); +int wifi_wps_enable_internal(const esp_wps_config_t *config); +int wifi_wps_disable_internal(void); +void wifi_station_wps_timeout_internal(void); +void wifi_station_wps_msg_timeout_internal(void); +void wifi_station_wps_success_internal(void); +void wifi_wps_scan_internal(void); +void wifi_station_wps_eapol_start_handle_internal(void); + +struct wps_sm *gWpsSm = NULL; +static wps_factory_information_t *s_factory_info = NULL; + +#ifdef CONFIG_WPS_TESTING +int wps_version_number = 0x20; +int wps_testing_dummy_cred = 0; +#endif /* CONFIG_WPS_TESTING */ + +int wps_get_type(void) +{ + return esp_wifi_get_wps_type_internal(); +} + +int wps_set_type(uint32_t type) +{ + return esp_wifi_set_wps_type_internal(type); +} + +int wps_get_status(void) +{ + return esp_wifi_get_wps_status_internal(); +} + +int wps_set_status(uint32_t status) +{ + return esp_wifi_set_wps_status_internal(status); +} + +static void wps_rxq_init(void) +{ + DATA_MUTEX_TAKE(); + STAILQ_INIT(&s_wps_rxq); + DATA_MUTEX_GIVE(); +} + +static void wps_rxq_enqueue(struct wps_rx_param *param) +{ + DATA_MUTEX_TAKE(); + STAILQ_INSERT_TAIL(&s_wps_rxq,param, bqentry); + DATA_MUTEX_GIVE(); +} + +static struct wps_rx_param * wps_rxq_dequeue(void) +{ + struct wps_rx_param *param = NULL; + DATA_MUTEX_TAKE(); + if ((param = STAILQ_FIRST(&s_wps_rxq)) != NULL) { + STAILQ_REMOVE_HEAD(&s_wps_rxq, bqentry); + STAILQ_NEXT(param,bqentry) = NULL; + } + DATA_MUTEX_GIVE(); + return param; +} + +static void wps_rxq_deinit(void) +{ + struct wps_rx_param *param = NULL; + DATA_MUTEX_TAKE(); + while ((param = STAILQ_FIRST(&s_wps_rxq)) != NULL) { + STAILQ_REMOVE_HEAD(&s_wps_rxq, bqentry); + STAILQ_NEXT(param,bqentry) = NULL; + os_free(param->buf); + os_free(param); + } + DATA_MUTEX_GIVE(); +} + +#ifdef USE_WPS_TASK +void wps_task(void *pvParameters ) +{ + ETSEvent *e; + wps_ioctl_param_t *param; + bool del_task = false; + + xSemaphoreGive(s_wps_task_create_sem); + + wpa_printf(MSG_DEBUG, "wps_Task enter"); + for (;;) { + if ( pdPASS == xQueueReceive(s_wps_queue, &e, portMAX_DELAY) ) { + + if ( (e->sig >= SIG_WPS_ENABLE) && (e->sig < SIG_WPS_NUM) ) { + DATA_MUTEX_TAKE(); + if (s_wps_sig_cnt[e->sig]) { + s_wps_sig_cnt[e->sig]--; + } else { + wpa_printf(MSG_ERROR, "wpsT: invalid sig cnt, sig=%d cnt=%d", e->sig, s_wps_sig_cnt[e->sig]); + } + DATA_MUTEX_GIVE(); + } + + wpa_printf(MSG_DEBUG, "wpsT: rx sig=%d", e->sig); + + switch (e->sig) { + case SIG_WPS_ENABLE: + case SIG_WPS_DISABLE: + case SIG_WPS_START: + param = (wps_ioctl_param_t *)e->par; + if (!param) { + wpa_printf(MSG_ERROR, "wpsT: invalid param sig=%d", e->sig); + xSemaphoreGive(s_wps_api_sem); + break; + } + + if (e->sig == SIG_WPS_ENABLE) { + param->ret = wifi_wps_enable_internal((esp_wps_config_t *)(param->arg)); + } else if (e->sig == SIG_WPS_DISABLE) { + param->ret = wifi_wps_disable_internal(); + del_task = true; + s_wps_task_hdl = NULL; + } else { + param->ret = wifi_station_wps_start(); + } + + xSemaphoreGive(s_wps_api_sem); + break; + + case SIG_WPS_RX: { + struct wps_rx_param *param = NULL; + while ((param = wps_rxq_dequeue()) != NULL) { + wps_sm_rx_eapol_internal(param->sa, param->buf, param->len); + os_free(param->buf); + os_free(param); + } + break; + } + + case SIG_WPS_TIMER_TIMEOUT: + wifi_station_wps_timeout_internal(); + break; + + case SIG_WPS_TIMER_MSG_TIMEOUT: + wifi_station_wps_msg_timeout_internal(); + break; + + case SIG_WPS_TIMER_SUCCESS_CB: + wifi_station_wps_success_internal(); + break; + + case SIG_WPS_TIMER_SCAN: + wifi_wps_scan_internal(); + break; + + case SIG_WPS_TIMER_EAPOL_START: + wifi_station_wps_eapol_start_handle_internal(); + break; + + default: + wpa_printf(MSG_ERROR, "wpsT: invalid sig=%d", e->sig); + break; + } + os_free(e); + + if (del_task) { + wpa_printf(MSG_DEBUG, "wpsT: delete task"); + break; + } + } + } + vTaskDelete(NULL); +} + +/* wps_post() is thread-safe + * + */ +int wps_post(uint32_t sig, uint32_t par) +{ + wpa_printf(MSG_DEBUG, "wps post: sig=%d cnt=%d", sig, s_wps_sig_cnt[sig]); + + DATA_MUTEX_TAKE(); + if (s_wps_sig_cnt[sig]) { + wpa_printf(MSG_DEBUG, "wps post: sig=%d processing", sig); + DATA_MUTEX_GIVE(); + return ESP_OK; + } else { + ETSEvent *evt = (ETSEvent *)os_malloc(sizeof(ETSEvent)); + + if (evt == NULL) { + wpa_printf(MSG_ERROR, "WPS: E N M"); + DATA_MUTEX_GIVE(); + return ESP_FAIL; + } + + s_wps_sig_cnt[sig]++; + evt->sig = sig; + evt->par = par; + DATA_MUTEX_GIVE(); + + if ( xQueueSend(s_wps_queue, &evt, 10 / portTICK_PERIOD_MS) != pdPASS) { + wpa_printf(MSG_ERROR, "WPS: Q S E"); + DATA_MUTEX_TAKE(); + s_wps_sig_cnt[sig]--; + DATA_MUTEX_GIVE(); + return ESP_FAIL; + } + } + return ESP_OK; +} +#endif + +static void wps_sendto_wrapper(void *buffer, uint16_t len) +{ + esp_wifi_internal_tx(WIFI_IF_STA, buffer, len); +} + +/* +* wps_sm_ether_send - Send Ethernet frame +* @wpa_s: Pointer to wpa_supplicant data +* @dest: Destination MAC address +* @proto: Ethertype in host byte order +* @buf: Frame payload starting from IEEE 802.1X header +* @len: Frame payload length +* Returns: >=0 on success, <0 on failure +*/ +static inline int wps_sm_ether_send(struct wps_sm *sm, const u8 *dest, u16 proto, + const u8 *data, size_t data_len) +{ + void *buffer = (void *)(data - sizeof(struct l2_ethhdr)); + struct l2_ethhdr *eth = (struct l2_ethhdr *)buffer; + + memcpy(eth->h_dest, dest, ETH_ALEN); + memcpy(eth->h_source, sm->ownaddr, ETH_ALEN); + eth->h_proto = host_to_be16(proto); + + wps_sendto_wrapper(buffer, sizeof(struct l2_ethhdr) + data_len); + + return ESP_OK; +} + + +u8 *wps_sm_alloc_eapol(struct wps_sm *sm, u8 type, + const void *data, u16 data_len, + size_t *msg_len, void **data_pos) +{ + void *buffer; + struct ieee802_1x_hdr *hdr; + + *msg_len = sizeof(struct ieee802_1x_hdr) + data_len; + /* XXX: reserve l2_ethhdr is enough */ + buffer = os_malloc(*msg_len + sizeof(struct l2_ethhdr)); + + if (buffer == NULL) { + return NULL; + } + hdr = (struct ieee802_1x_hdr *)((char *)buffer + sizeof(struct l2_ethhdr)); + + hdr->version = sm->eapol_version; + hdr->type = type; + hdr->length = host_to_be16(data_len); + + if (data) { + memcpy(hdr + 1, data, data_len); + } else { + memset(hdr + 1, 0, data_len); + } + + if (data_pos) { + *data_pos = hdr + 1; + } + + return (u8 *) hdr; +} + + +void wps_sm_free_eapol(u8 *buffer) +{ + if (buffer != NULL) { + buffer = buffer - sizeof(struct l2_ethhdr); + os_free(buffer); + } +} + + +/** + * wps_init - Initialize WPS Registration protocol data + * @cfg: WPS configuration + * Returns: Pointer to allocated data or %NULL on failure + * + * This function is used to initialize WPS data for a registration protocol + * instance (i.e., each run of registration protocol as a Registrar of + * Enrollee. The caller is responsible for freeing this data after the + * registration run has been completed by calling wps_deinit(). + */ +struct wps_data *wps_init(void) +{ + struct wps_sm *sm = gWpsSm; + struct wps_data *data = (struct wps_data *)os_zalloc(sizeof(*data)); + const char *all_zero_pin = "00000000"; + + if (data == NULL) { + return NULL; + } + + data->wps = sm->wps_ctx; + + if (IS_WPS_REGISTRAR(wps_get_type())) { + data->registrar = 1; + } else { + data->registrar = 0; + } + + data->registrar = 0; /* currently, we force to support enrollee only */ + + if (data->registrar) { + memcpy(data->uuid_r, sm->uuid, WPS_UUID_LEN); + } else { + memcpy(data->mac_addr_e, sm->dev->mac_addr, ETH_ALEN); + memcpy(data->uuid_e, sm->uuid, WPS_UUID_LEN); + } + + if (wps_get_type() == WPS_TYPE_PIN) { + u32 spin = 0; + data->dev_pw_id = DEV_PW_DEFAULT; + data->dev_password_len = 8; + data->dev_password = (u8 *) os_zalloc(data->dev_password_len + 1); + if (data->dev_password == NULL) { + os_free(data); + return NULL; + } + + spin = wps_generate_pin(); + sprintf((char *)data->dev_password, "%08d", spin); + wpa_hexdump_key(MSG_DEBUG, "WPS: AP PIN dev_password", + data->dev_password, data->dev_password_len); + do { + char tmpp[9]; + os_bzero(tmpp, 9); + memcpy(tmpp, data->dev_password, 8); + wpa_printf(MSG_DEBUG, "WPS PIN [%s]", tmpp); + system_event_t evt; + evt.event_id = SYSTEM_EVENT_STA_WPS_ER_PIN; + memcpy(evt.event_info.sta_er_pin.pin_code, data->dev_password, 8); + esp_event_send(&evt); + } while (0); + } else if (wps_get_type() == WPS_TYPE_PBC) { + data->pbc = 1; + /* Use special PIN '00000000' for PBC */ + data->dev_pw_id = DEV_PW_PUSHBUTTON; + if (data->dev_password) { + os_free(data->dev_password); + } + data->dev_password = (u8 *) os_zalloc(9); + if (data->dev_password == NULL) { + os_free(data); + return NULL; + } else { + strncpy((char *)data->dev_password, all_zero_pin, 9); + } + data->dev_password_len = 8; + } + +#ifdef CONFIG_WPS_NFC + if (cfg->wps->ap && !cfg->registrar && cfg->wps->ap_nfc_dev_pw_id) { + data->dev_pw_id = cfg->wps->ap_nfc_dev_pw_id; + os_free(data->dev_password); + data->dev_password = + os_malloc(wpabuf_len(cfg->wps->ap_nfc_dev_pw)); + if (data->dev_password == NULL) { + os_free(data); + return NULL; + } + memcpy(data->dev_password, + wpabuf_head(cfg->wps->ap_nfc_dev_pw), + wpabuf_len(cfg->wps->ap_nfc_dev_pw)); + data->dev_password_len = wpabuf_len(cfg->wps->ap_nfc_dev_pw); + } +#endif /* CONFIG_WPS_NFC */ + data->wps->config_methods = WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_DISPLAY; +#ifdef CONFIG_WPS2 + data->wps->config_methods |= (WPS_CONFIG_VIRT_PUSHBUTTON | WPS_CONFIG_PHY_DISPLAY); +#endif + + data->state = data->registrar ? RECV_M1 : SEND_M1; + + return data; +} + + +/** + * wps_deinit - Deinitialize WPS Registration protocol data + * @data: WPS Registration protocol data from wps_init() + */ +void wps_deinit(void) +{ + struct wps_data *data = gWpsSm->wps; + +#ifdef CONFIG_WPS_NFC + if (data->registrar && data->nfc_pw_token) + wps_registrar_remove_nfc_pw_token(data->wps->registrar, + data->nfc_pw_token); +#endif /* CONFIG_WPS_NFC */ + + if (data->wps_pin_revealed) { + wpa_printf(MSG_DEBUG, "WPS: Full PIN information revealed and " + "negotiation failed"); + } else if (data->registrar) + wpa_printf(MSG_DEBUG, "WPS: register information revealed and " + "negotiation failed"); + wpabuf_free(data->dh_privkey); + +#ifdef DESP8266_WORKAROUND + /* + * 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 + * which would cause WPS fail, so we clean the key after WPS finished . + */ + data->dh_privkey = NULL; +#endif //DESP32_WORKAROUND + + wpabuf_free(data->dh_pubkey_e); + wpabuf_free(data->dh_pubkey_r); + wpabuf_free(data->last_msg); + os_free(data->dev_password); + dh5_free(data->dh_ctx); + wps_dev_deinit(&data->peer_dev); +#ifdef CONFIG_WPS_NFC + os_free(data->nfc_pw_token); +#endif + os_free(data); +} + +static void +wps_build_ic_appie_wps_pr(void) +{ + struct wpabuf *extra_ie = NULL; + struct wpabuf *wps_ie; + struct wps_sm *sm = gWpsSm; + + wpa_printf(MSG_DEBUG, "wps build: wps pr"); + + if (wps_get_type() == WPS_TYPE_PBC) { + wps_ie = (struct wpabuf *)wps_build_probe_req_ie(DEV_PW_PUSHBUTTON, + sm->dev, + sm->uuid, WPS_REQ_ENROLLEE, + 0, NULL); + } else { + wps_ie = (struct wpabuf *)wps_build_probe_req_ie(DEV_PW_DEFAULT, + sm->dev, + sm->uuid, WPS_REQ_ENROLLEE, + 0, NULL); + } + + if (wps_ie) { + if (wpabuf_resize(&extra_ie, wpabuf_len(wps_ie)) == 0) { + wpabuf_put_buf(extra_ie, wps_ie); + } else { + wpabuf_free(wps_ie); + return; + } + wpabuf_free(wps_ie); + } + + esp_wifi_set_appie_internal(WIFI_APPIE_WPS_PR, (uint8_t *)wpabuf_head(extra_ie), extra_ie->used, 0); + wpabuf_free(extra_ie); +} + +static void +wps_build_ic_appie_wps_ar(void) +{ + struct wpabuf *buf = (struct wpabuf *)wps_build_assoc_req_ie(WPS_REQ_ENROLLEE); + + wpa_printf(MSG_DEBUG, "wps build: wps ar"); + + if (buf) { + esp_wifi_set_appie_internal(WIFI_APPIE_WPS_AR, (uint8_t *)wpabuf_head(buf), buf->used, 0); + wpabuf_free(buf); + } +} + +static bool +wps_parse_scan_result(struct wps_scan_ie *scan) +{ + struct wps_sm *sm = gWpsSm; + wifi_mode_t op_mode = 0; +#ifdef WPS_DEBUG + char tmp[32]; + + os_bzero(tmp, 32); + strncpy(tmp, (char *)&scan->ssid[2], (int)scan->ssid[1]); + wpa_printf(MSG_DEBUG, "wps parse scan: %s", tmp); +#endif + + if (wps_get_type() == WPS_TYPE_DISABLE + || (wps_get_status() != WPS_STATUS_DISABLE + && wps_get_status() != WPS_STATUS_SCANNING) + ) { + return false; + } + + esp_wifi_get_mode(&op_mode); + if ((op_mode == WIFI_MODE_STA || op_mode == WIFI_MODE_APSTA) && scan->wps) { + struct wpabuf *buf = wpabuf_alloc_copy(scan->wps + 6, scan->wps[1] - 4); + + if (wps_is_selected_pbc_registrar(buf, scan->bssid) + || wps_is_selected_pin_registrar(buf, scan->bssid)) { + wpabuf_free(buf); + + if (sm->is_wps_scan == false) { + return false; + } + if (memcmp(sm->config.bssid, scan->bssid, ETH_ALEN) != 0 ) { + sm->discover_ssid_cnt++; + } + + if (!scan->rsn && !scan->wpa && (scan->capinfo & WIFI_CAPINFO_PRIVACY)) { + wpa_printf(MSG_ERROR, "WEP not suppported in WPS"); + + return false; + } + + esp_wifi_enable_sta_privacy_internal(); + strncpy((char *)sm->config.ssid, (char *)&scan->ssid[2], (int)scan->ssid[1]); + if (scan->bssid) { + memcpy(gWpsSm->bssid, scan->bssid, ETH_ALEN); + memcpy(sm->config.bssid, scan->bssid, ETH_ALEN); + sm->config.bssid_set = 1; + } else { + } + wpa_printf(MSG_DEBUG, "wps discover [%s]", (char *)sm->config.ssid); + sm->scan_cnt = 0; + + sm->channel = scan->chan; + + return true; + } + wpabuf_free(buf); + } + + return false; +} + +int wps_send_eap_identity_rsp(u8 id) +{ + struct wps_sm *sm = gWpsSm; + struct wpabuf *eap_buf = NULL; + u8 bssid[6]; + u8 *buf = NULL; + int len; + int ret = ESP_OK; + + wpa_printf(MSG_DEBUG, "wps send eapol id rsp"); + eap_buf = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY, sm->identity_len, + EAP_CODE_RESPONSE, id); + if (!eap_buf) { + ret = ESP_FAIL; + goto _err; + } + + ret = esp_wifi_get_assoc_bssid_internal(bssid); + if (ret != 0) { + wpa_printf(MSG_ERROR, "bssid is empty!"); + return ESP_FAIL; + } + + wpabuf_put_data(eap_buf, sm->identity, sm->identity_len); + + buf = wps_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAP_PACKET, wpabuf_head_u8(eap_buf), wpabuf_len(eap_buf), (size_t *)&len, NULL); + if (!buf) { + ret = ESP_ERR_NO_MEM; + goto _err; + } + + ret = wps_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len); + if (ret) { + ret = ESP_FAIL; + goto _err; + } + +_err: + wps_sm_free_eapol(buf); + wpabuf_free(eap_buf); + return ret; +} + +int wps_send_frag_ack(u8 id) +{ + struct wps_sm *sm = gWpsSm; + struct wpabuf *eap_buf = NULL; + u8 bssid[6]; + u8 *buf; + int len; + int ret = 0; + enum wsc_op_code opcode = WSC_FRAG_ACK; + + wpa_printf(MSG_DEBUG, "send frag ack id:%d", id); + + if (!sm) { + return ESP_FAIL; + } + + ret = esp_wifi_get_assoc_bssid_internal(bssid); + if (ret != 0) { + wpa_printf(MSG_ERROR, "bssid is empty!"); + return ret; + } + + eap_buf = eap_msg_alloc(EAP_VENDOR_WFA, 0x00000001, 2, EAP_CODE_RESPONSE, id); + if (!eap_buf) { + ret = ESP_ERR_NO_MEM; + goto _err; + } + + wpabuf_put_u8(eap_buf, opcode); + wpabuf_put_u8(eap_buf, 0x00); /* flags */ + + buf = wps_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAP_PACKET, wpabuf_head_u8(eap_buf), wpabuf_len(eap_buf), (size_t *)&len, NULL); + if (!buf) { + ret = ESP_ERR_NO_MEM; + goto _err; + } + + ret = wps_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len); + wps_sm_free_eapol(buf); + if (ret) { + ret = ESP_ERR_NO_MEM; + goto _err; + } + +_err: + wpabuf_free(eap_buf); + return ret; +} + +int wps_enrollee_process_msg_frag(struct wpabuf **buf, int tot_len, u8 *frag_data, int frag_len, u8 flag) +{ + struct wps_sm *sm = gWpsSm; + u8 identifier; + + if (!sm) { + return ESP_FAIL; + } + + identifier = sm->current_identifier; + + if (buf == NULL || frag_data == NULL) { + wpa_printf(MSG_ERROR, "fun:%s. line:%d, frag buf or frag data is null", __FUNCTION__, __LINE__); + return ESP_FAIL; + } + + if (*buf == NULL) { + if (0 == (flag & WPS_MSG_FLAG_LEN) || tot_len < frag_len) { + wpa_printf(MSG_ERROR, "fun:%s. line:%d, flag error:%02x", __FUNCTION__, __LINE__, flag); + return ESP_FAIL; + } + + *buf = wpabuf_alloc(tot_len); + if (*buf == NULL) { + return ESP_ERR_NO_MEM; + } + + wpabuf_put_data(*buf, frag_data, frag_len); + return wps_send_frag_ack(identifier); + } + + if (flag & WPS_MSG_FLAG_LEN) { + wpa_printf(MSG_ERROR, "fun:%s. line:%d, flag error:%02x", __FUNCTION__, __LINE__, flag); + return ESP_FAIL; + } + + wpabuf_put_data(*buf, frag_data, frag_len); + + if (flag & WPS_MSG_FLAG_MORE) { + return wps_send_frag_ack(identifier); + } + + return ESP_OK; +} + +int wps_process_wps_mX_req(u8 *ubuf, int len, enum wps_process_res *res) +{ + struct wps_sm *sm = gWpsSm; + static struct wpabuf *wps_buf = NULL; + struct eap_expand *expd; + int tlen = 0; + u8 *tbuf; + u8 flag; + int frag_len; + u16 be_tot_len = 0; + + if (!sm) { + return ESP_FAIL; + } + + expd = (struct eap_expand *) ubuf; + wpa_printf(MSG_DEBUG, "wps process mX req: len %d, tlen %d", len, tlen); + + flag = *(u8 *)(ubuf + sizeof(struct eap_expand)); + if (flag & WPS_MSG_FLAG_LEN) { + tbuf = ubuf + sizeof(struct eap_expand) + 1 + 2;//two bytes total length + frag_len = len - (sizeof(struct eap_expand) + 1 + 2); + be_tot_len = *(u16 *)(ubuf + sizeof(struct eap_expand) + 1); + tlen = ((be_tot_len & 0xff) << 8) | ((be_tot_len >> 8) & 0xff); + } else { + tbuf = ubuf + sizeof(struct eap_expand) + 1; + frag_len = len - (sizeof(struct eap_expand) + 1); + tlen = frag_len; + } + + if ((flag & WPS_MSG_FLAG_MORE) || wps_buf != NULL) {//frag msg + 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); + if (ESP_OK != wps_enrollee_process_msg_frag(&wps_buf, tlen, tbuf, frag_len, flag)) { + if (wps_buf) { + wpabuf_free(wps_buf); + wps_buf = NULL; + } + return ESP_FAIL; + } + if (flag & WPS_MSG_FLAG_MORE) { + if (res) { + *res = WPS_FRAGMENT; + } + return ESP_OK; + } + } else { //not frag msg + if (wps_buf) {//if something wrong, frag msg buf is not freed, free first + wpa_printf(MSG_ERROR, "something is wrong, frag buf is not freed"); + wpabuf_free(wps_buf); + wps_buf = NULL; + } + wps_buf = wpabuf_alloc_copy(tbuf, tlen); + } + + if (!wps_buf) { + return ESP_FAIL; + } + + ets_timer_disarm(&sm->wps_msg_timeout_timer); + + if (res) { + *res = wps_enrollee_process_msg(sm->wps, expd->opcode, wps_buf); + } else { + wps_enrollee_process_msg(sm->wps, expd->opcode, wps_buf); + } + + if (wps_buf) { + wpabuf_free(wps_buf); + wps_buf = NULL; + } + return ESP_OK; +} + +int wps_send_wps_mX_rsp(u8 id) +{ + struct wps_sm *sm = gWpsSm; + struct wpabuf *eap_buf = NULL; + struct wpabuf *wps_buf = NULL; + u8 bssid[6]; + u8 *buf; + int len; + int ret = 0; + enum wsc_op_code opcode; + + wpa_printf(MSG_DEBUG, "wps send wps mX rsp"); + + if (!sm) { + return ESP_FAIL; + } + + ret = esp_wifi_get_assoc_bssid_internal(bssid); + if (ret != 0) { + wpa_printf(MSG_ERROR, "bssid is empty!"); + return ret; + } + + wps_buf = (struct wpabuf *)wps_enrollee_get_msg(sm->wps, &opcode); + if (!wps_buf) { + ret = ESP_FAIL; + goto _err; + } + + eap_buf = eap_msg_alloc(EAP_VENDOR_WFA, 0x00000001, wpabuf_len(wps_buf) + 2, EAP_CODE_RESPONSE, id); + if (!eap_buf) { + ret = ESP_FAIL; + goto _err; + } + + wpabuf_put_u8(eap_buf, opcode); + wpabuf_put_u8(eap_buf, 0x00); /* flags */ + wpabuf_put_data(eap_buf, wpabuf_head_u8(wps_buf), wpabuf_len(wps_buf)); + + + wpabuf_free(wps_buf); + + buf = wps_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAP_PACKET, wpabuf_head_u8(eap_buf), wpabuf_len(eap_buf), (size_t *)&len, NULL); + if (!buf) { + ret = ESP_FAIL; + goto _err; + } + + ret = wps_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len); + wps_sm_free_eapol(buf); + if (ret) { + ret = ESP_FAIL; + goto _err; + } + +_err: + wpabuf_free(eap_buf); + return ret; +} + + + +int wps_tx_start(void) +{ + struct wps_sm *sm = gWpsSm; + u8 bssid[6]; + u8 *buf; + int len; + int ret = 0; + + ret = esp_wifi_get_assoc_bssid_internal(bssid); + if (ret != 0) { + wpa_printf(MSG_ERROR, "bssid is empty!"); + return ret; + } + + if (!sm) { + return ESP_FAIL; + } + + wpa_printf(MSG_DEBUG, "WPS: Send EAPOL START."); + buf = wps_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START, (u8 *)"", 0, (size_t *)&len, NULL); + if (!buf) { + return ESP_ERR_NO_MEM; + } + + wps_sm_ether_send(sm, bssid, ETH_P_EAPOL, buf, len); + wps_sm_free_eapol(buf); + + ets_timer_arm(&sm->wps_eapol_start_timer, 3000, 0); + + return ESP_OK; +} + +int wps_start_pending(void) +{ + if (!gWpsSm) { + return ESP_FAIL; + } + + wpa_printf(MSG_DEBUG, "wps start pending"); + return wps_tx_start(); +} + +int wps_stop_process(system_event_sta_wps_fail_reason_t reason_code) +{ + struct wps_sm *sm = gWpsSm; + + if (!gWpsSm) { + return ESP_FAIL; + } + + wps_set_status(WPS_STATUS_DISABLE); + sm->scan_cnt = 0; + sm->discover_ssid_cnt = 0; + sm->wps->state = SEND_M1; + os_bzero(sm->bssid, ETH_ALEN); + os_bzero(sm->ssid, sizeof(sm->ssid)); + os_bzero(sm->ssid_len, sizeof(sm->ssid_len)); + os_bzero((u8 *)&sm->config, sizeof(wifi_sta_config_t)); + sm->ap_cred_cnt = 0; + + esp_wifi_disarm_sta_connection_timer_internal(); + ets_timer_disarm(&sm->wps_msg_timeout_timer); + ets_timer_disarm(&sm->wps_success_cb_timer); + + esp_wifi_disconnect(); + + wpa_printf(MSG_DEBUG, "Write wps_fail_information"); + system_event_t evt; + evt.event_id = SYSTEM_EVENT_STA_WPS_ER_FAILED; + evt.event_info.sta_er_fail_reason = reason_code; + esp_event_send(&evt); + return ESP_OK; +} + +int wps_finish(void) +{ + struct wps_sm *sm = gWpsSm; + int ret = ESP_FAIL; + + if (!gWpsSm) { + return ESP_FAIL; + } + + if (sm->wps->state == WPS_FINISHED) { + wifi_config_t *config = (wifi_config_t *)os_zalloc(sizeof(wifi_config_t)); + + if (config == NULL) { + system_event_t evt; + evt.event_id = SYSTEM_EVENT_STA_WPS_ER_FAILED; + esp_event_send(&evt); + return ESP_FAIL; + } + + wpa_printf(MSG_DEBUG, "wps finished------>"); + wps_set_status(WPS_STATUS_SUCCESS); + esp_wifi_disarm_sta_connection_timer_internal(); + ets_timer_disarm(&sm->wps_timeout_timer); + ets_timer_disarm(&sm->wps_msg_timeout_timer); + + if (sm->ap_cred_cnt == 1) { + memset(config, 0x00, sizeof(wifi_sta_config_t)); + memcpy(config->sta.ssid, sm->ssid[0], sm->ssid_len[0]); + memcpy(config->sta.password, sm->key[0], sm->key_len[0]); + memcpy(config->sta.bssid, sm->bssid, ETH_ALEN); + config->sta.bssid_set = 0; + esp_wifi_set_config(0, config); + + os_free(config); + config = NULL; + } + ets_timer_disarm(&sm->wps_success_cb_timer); + ets_timer_arm(&sm->wps_success_cb_timer, 1000, 0); + + ret = 0; + } else { + wpa_printf(MSG_ERROR, "wps failed----->"); + + ret = wps_stop_process(WPS_FAIL_REASON_NORMAL); + } + + return ret; +} + +/* Add current ap to discard ap list */ +void wps_add_discard_ap(u8 *bssid) +{ + struct wps_sm *sm = gWpsSm; + u8 cnt = sm->discard_ap_cnt; + + if (!gWpsSm || !bssid) { + return; + } + + if (sm->discard_ap_cnt < WPS_MAX_DIS_AP_NUM) { + sm->discard_ap_cnt++; + } else { + for (cnt = 0; cnt < WPS_MAX_DIS_AP_NUM - 2; cnt++) { + memcpy(sm->dis_ap_list[cnt].bssid, sm->dis_ap_list[cnt + 1].bssid, 6); + } + sm->discard_ap_cnt = WPS_MAX_DIS_AP_NUM; + } + memcpy(sm->dis_ap_list[cnt].bssid, bssid, 6); +} + +int wps_start_msg_timer(void) +{ + struct wps_sm *sm = gWpsSm; + uint32_t msg_timeout; + int ret = ESP_FAIL; + + if (!gWpsSm) { + return ESP_FAIL; + } + + if (sm->wps->state == WPS_FINISHED) { + msg_timeout = 100; + wpa_printf(MSG_DEBUG, "start msg timer WPS_FINISHED %d ms", msg_timeout); + ets_timer_disarm(&sm->wps_msg_timeout_timer); + ets_timer_arm(&sm->wps_msg_timeout_timer, msg_timeout, 0); + ret = 0; + } else if (sm->wps->state == RECV_M2) { + msg_timeout = 5000; + wpa_printf(MSG_DEBUG, "start msg timer RECV_M2 %d ms", msg_timeout); + ets_timer_disarm(&sm->wps_msg_timeout_timer); + ets_timer_arm(&sm->wps_msg_timeout_timer, msg_timeout, 0); + ret = 0; + } + return ret; +} + +/** + * wps_sm_rx_eapol - Process received WPA EAPOL frames + * @sm: Pointer to WPA state machine data from wpa_sm_init() + * @src_addr: Source MAC address of the EAPOL packet + * @buf: Pointer to the beginning of the EAPOL data (EAPOL header) + * @len: Length of the EAPOL frame + * Returns: 1 = WPA EAPOL-Key processed, ESP_OK = not a WPA EAPOL-Key, ESP_FAIL failure + * + * This function is called for each received EAPOL frame. Other than EAPOL-Key + * frames can be skipped if filtering is done elsewhere. wpa_sm_rx_eapol() is + * only processing WPA and WPA2 EAPOL-Key frames. + * + * The received EAPOL-Key packets are validated and valid packets are replied + * to. In addition, key material (PTK, GTK) is configured at the end of a + * successful key handshake. + * buf begin from version, so remove mac header ,snap header and ether_type + */ +int wps_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len) +{ + if (!gWpsSm) { + return ESP_FAIL; + } + +#ifdef USE_WPS_TASK + { + struct wps_rx_param *param = (struct wps_rx_param *)os_zalloc(sizeof(struct wps_rx_param)); /* free in task */ + + if (!param) { + return ESP_ERR_NO_MEM; + } + + param->buf = (u8 *)os_zalloc(len); /* free in task */ + if (!param->buf) { + os_free(param); + return ESP_ERR_NO_MEM; + } + memcpy(param->buf, buf, len); + param->len = len; + memcpy(param->sa, src_addr, WPS_ADDR_LEN); + + wps_rxq_enqueue(param); + return wps_post(SIG_WPS_RX, 0); + } +#else + return wps_sm_rx_eapol_internal(src_addr, buf, len); +#endif +} + +int wps_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len) +{ + struct wps_sm *sm = gWpsSm; + u32 plen, data_len, eap_len; + struct ieee802_1x_hdr *hdr; + struct eap_hdr *ehdr; + u8 *tmp; + u8 eap_code; + u8 eap_type; + int ret = ESP_FAIL; + enum wps_process_res res = WPS_DONE; + + if (!gWpsSm) { + return ESP_FAIL; + } + + if (len < sizeof(*hdr) + sizeof(*ehdr)) { +#ifdef DEBUG_PRINT + wpa_printf(MSG_DEBUG, "WPA: EAPOL frame too short to be a WPA " + "EAPOL-Key (len %lu, expecting at least %lu)", + (unsigned long) len, + (unsigned long) sizeof(*hdr) + sizeof(*ehdr)); +#endif + return ESP_OK; + } + + tmp = buf; + + hdr = (struct ieee802_1x_hdr *) tmp; + ehdr = (struct eap_hdr *) (hdr + 1); + plen = be_to_host16(hdr->length); + data_len = plen + sizeof(*hdr); + eap_len = be_to_host16(ehdr->length); + +#ifdef DEBUG_PRINT + wpa_printf(MSG_DEBUG, "IEEE 802.1X RX: version=%d type=%d length=%d", + hdr->version, hdr->type, plen); +#endif + + if (hdr->version < EAPOL_VERSION) { + /* TODO: backwards compatibility */ + } + if (hdr->type != IEEE802_1X_TYPE_EAP_PACKET) { +#ifdef DEBUG_PRINT + wpa_printf(MSG_DEBUG, "WPS: EAP frame (type %u) discarded, " + "not a EAP PACKET frame", hdr->type); +#endif + ret = 0; + goto out; + } + if (plen > len - sizeof(*hdr) || plen < sizeof(*ehdr)) { +#ifdef DEBUG_PRINT + wpa_printf(MSG_DEBUG, "WPA: EAPOL frame payload size %lu " + "invalid (frame size %lu)", + (unsigned long) plen, (unsigned long) len); +#endif + ret = 0; + goto out; + } + + wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL-EAP PACKET", tmp, len); + + if (data_len < len) { +#ifdef DEBUG_PRINT + wpa_printf(MSG_DEBUG, "WPA: ignoring %lu bytes after the IEEE " + "802.1X data", (unsigned long) len - data_len); +#endif + } + + if (eap_len != plen) { +#ifdef DEBUG_PRINT + wpa_printf(MSG_DEBUG, "WPA: EAPOL length %lu " + "invalid (eapol length %lu)", + (unsigned long) eap_len, (unsigned long) plen); +#endif + ret = 0; + goto out; + } + + eap_code = ehdr->code; + switch (eap_code) { + case EAP_CODE_SUCCESS: + wpa_printf(MSG_DEBUG, "error: receive eapol success frame!"); + ret = 0; + break; + case EAP_CODE_FAILURE: + wpa_printf(MSG_DEBUG, "receive eap code failure!"); + ret = wps_finish(); + break; + case EAP_CODE_RESPONSE: + wpa_printf(MSG_DEBUG, "error: receive eapol response frame!"); + ret = 0; + break; + case EAP_CODE_REQUEST: { + eap_type = ((u8 *)ehdr)[sizeof(*ehdr)]; + switch (eap_type) { + case EAP_TYPE_IDENTITY: + wpa_printf(MSG_DEBUG, "=========identity==========="); + sm->current_identifier = ehdr->identifier; + ets_timer_disarm(&sm->wps_eapol_start_timer); + wpa_printf(MSG_DEBUG, "WPS: Build EAP Identity."); + ret = wps_send_eap_identity_rsp(ehdr->identifier); + ets_timer_arm(&sm->wps_eapol_start_timer, 3000, 0); + break; + case EAP_TYPE_EXPANDED: + wpa_printf(MSG_DEBUG, "=========expanded plen[%d], %d===========", plen, sizeof(*ehdr)); + if (ehdr->identifier == sm->current_identifier) { + ret = 0; + wpa_printf(MSG_DEBUG, "wps: ignore overlap identifier"); + goto out; + } + sm->current_identifier = ehdr->identifier; + + tmp = (u8 *)(ehdr + 1) + 1; + ret = wps_process_wps_mX_req(tmp, plen - sizeof(*ehdr) - 1, &res); + if (ret == 0 && res != WPS_FAILURE && res != WPS_IGNORE && res != WPS_FRAGMENT) { + ret = wps_send_wps_mX_rsp(ehdr->identifier); + if (ret == 0) { + wpa_printf(MSG_DEBUG, "sm->wps->state = %d", sm->wps->state); + wps_start_msg_timer(); + } + } else if (ret == 0 && res == WPS_FRAGMENT) { + wpa_printf(MSG_DEBUG, "wps frag, continue..."); + ret = ESP_OK; + } else if (res == WPS_IGNORE) { + wpa_printf(MSG_DEBUG, "IGNORE overlap Mx"); + ret = ESP_OK; /* IGNORE the overlap */ + } else { + ret = ESP_FAIL; + } + break; + default: + break; + } + break; + } + default: + break; + } +out: + if (ret != 0 || res == WPS_FAILURE) { + wpa_printf(MSG_DEBUG, "wpa rx eapol internal: fail ret=%d", ret); + wps_set_status(WPS_STATUS_DISABLE); + esp_wifi_disarm_sta_connection_timer_internal(); + ets_timer_disarm(&sm->wps_timeout_timer); + + system_event_t evt; + evt.event_id = SYSTEM_EVENT_STA_WPS_ER_FAILED; + esp_event_send(&evt); + + return ret; + } + + return ret; +} + +int wps_set_default_factory(void) +{ + if (!s_factory_info) { + s_factory_info = os_zalloc(sizeof(wps_factory_information_t)); + if (!s_factory_info) { + wpa_printf(MSG_ERROR, "wps factory info malloc failed"); + return ESP_ERR_NO_MEM; + } + } + + sprintf(s_factory_info->manufacturer, "ESPRESSIF"); + sprintf(s_factory_info->model_name, "ESPRESSIF IOT"); + sprintf(s_factory_info->model_number, "ESP8266"); + sprintf(s_factory_info->device_name, "ESP8266 STATION"); + + return ESP_OK; +} + +int wps_set_factory_info(const esp_wps_config_t *config) +{ + int ret; + + ret = wps_set_default_factory(); + if (ret != 0) { + return ret; + } + + if (config->factory_info.manufacturer[0] != 0) { + memcpy(s_factory_info->manufacturer, config->factory_info.manufacturer, WPS_MAX_MANUFACTURER_LEN - 1); + } + + if (config->factory_info.model_number[0] != 0) { + memcpy(s_factory_info->model_number, config->factory_info.model_number, WPS_MAX_MODEL_NUMBER_LEN - 1); + } + + if (config->factory_info.model_name[0] != 0) { + memcpy(s_factory_info->model_name, config->factory_info.model_name, WPS_MAX_MODEL_NAME_LEN - 1); + } + + if (config->factory_info.device_name[0] != 0) { + memcpy(s_factory_info->device_name, config->factory_info.device_name, WPS_MAX_DEVICE_NAME_LEN - 1); + } + + wpa_printf(MSG_INFO, "manufacturer: %s, model number: %s, model name: %s, device name: %s", s_factory_info->manufacturer, + s_factory_info->model_number, s_factory_info->model_name, s_factory_info->device_name); + + return ESP_OK; +} + + +int wps_dev_init(void) +{ + int ret = 0; + struct wps_sm *sm = gWpsSm; + struct wps_device_data *dev = NULL; + + if (!sm) { + ret = ESP_FAIL; + goto _out; + } + + dev = &sm->wps_ctx->dev; + sm->dev = dev; + + if (!dev) { + ret = ESP_FAIL; + goto _out; + } + dev->config_methods = WPS_CONFIG_VIRT_PUSHBUTTON | WPS_CONFIG_PHY_DISPLAY; + dev->rf_bands = WPS_RF_24GHZ; + + WPA_PUT_BE16(dev->pri_dev_type, WPS_DEV_COMPUTER); + WPA_PUT_BE32(dev->pri_dev_type + 2, WPS_DEV_OUI_WFA); + WPA_PUT_BE16(dev->pri_dev_type + 6, WPS_DEV_COMPUTER_PC); + + if (!s_factory_info) { + ret = wps_set_default_factory(); + if (ret != 0) { + goto _out; + } + } + + dev->manufacturer = (char *)os_zalloc(WPS_MAX_MANUFACTURER_LEN); + if (!dev->manufacturer) { + ret = ESP_FAIL; + goto _out; + } + sprintf(dev->manufacturer, s_factory_info->manufacturer); + + dev->model_name = (char *)os_zalloc(WPS_MAX_MODEL_NAME_LEN); + if (!dev->model_name) { + ret = ESP_FAIL; + goto _out; + } + sprintf(dev->model_name, s_factory_info->model_name); + + dev->model_number = (char *)os_zalloc(WPS_MAX_MODEL_NAME_LEN); + if (!dev->model_number) { + ret = ESP_FAIL; + goto _out; + } + sprintf(dev->model_number, s_factory_info->model_number); + + dev->device_name = (char *)os_zalloc(WPS_MAX_DEVICE_NAME_LEN); + if (!dev->device_name) { + ret = ESP_FAIL; + goto _out; + } + sprintf(dev->device_name, s_factory_info->device_name); + + dev->serial_number = (char *)os_zalloc(16); + if (!dev->serial_number) { + ret = ESP_FAIL; + goto _out; + } + sprintf(dev->serial_number, "%02x%02x%02x%02x%02x%02x", + sm->ownaddr[0], sm->ownaddr[1], sm->ownaddr[2], + sm->ownaddr[3], sm->ownaddr[4], sm->ownaddr[5]); + + uuid_gen_mac_addr(sm->ownaddr, sm->uuid); + memcpy(dev->mac_addr, sm->ownaddr, ETH_ALEN); + + return ESP_OK; + +_out: + if (dev->manufacturer) { + os_free(dev->manufacturer); + } + if (dev->model_name) { + os_free(dev->model_name); + } + if (dev->model_number) { + os_free(dev->model_number); + } + if (dev->device_name) { + os_free(dev->device_name); + } + if (dev->serial_number) { + os_free(dev->serial_number); + } + + if (s_factory_info) { + os_free(s_factory_info); + s_factory_info = NULL; + } + + return ret; +} + + +int wps_dev_deinit(struct wps_device_data *dev) +{ + int ret = 0; + + if (!dev) { + return ESP_FAIL; + } + + if (dev->manufacturer) { + os_free(dev->manufacturer); + } + if (dev->model_name) { + os_free(dev->model_name); + } + if (dev->model_number) { + os_free(dev->model_number); + } + if (dev->device_name) { + os_free(dev->device_name); + } + if (dev->serial_number) { + os_free(dev->serial_number); + } + + if (s_factory_info) { + os_free(s_factory_info); + s_factory_info = NULL; + } + + return ret; +} + +void +wifi_station_wps_timeout_internal(void) +{ + struct wps_sm *sm = gWpsSm; + + if (!sm) { + return; + } + + esp_wifi_disarm_sta_connection_timer_internal(); + + wps_set_status(WPS_STATUS_DISABLE); + + system_event_t evt; + evt.event_id = SYSTEM_EVENT_STA_WPS_ER_TIMEOUT; + esp_event_send(&evt); + +} + +void wifi_station_wps_timeout(void) +{ +#ifdef USE_WPS_TASK + wps_post(SIG_WPS_TIMER_TIMEOUT, 0); + return; +#else + wifi_station_wps_timeout_internal(); +#endif +} + +void +wifi_station_wps_msg_timeout_internal(void) +{ + struct wps_sm *sm = gWpsSm; + + if (!sm) { + return; + } + + if (sm->wps->state == WPS_FINISHED) { + wpa_printf(MSG_DEBUG, "wps msg timeout WPS_FINISHED"); + wps_finish(); + } else if (sm->wps->state == RECV_M2) { + wpa_printf(MSG_DEBUG, "wps msg timeout RECV_M2"); + wpa_printf(MSG_DEBUG, "wps recev m2/m2d timeout------>"); + wps_add_discard_ap(sm->config.bssid); + wps_stop_process(WPS_FAIL_REASON_RECV_M2D); + } +} + +void wifi_station_wps_msg_timeout(void) +{ +#ifdef USE_WPS_TASK + wps_post(SIG_WPS_TIMER_MSG_TIMEOUT, 0); + return; +#else + wifi_station_wps_msg_timeout_internal(); +#endif +} + +void wifi_station_wps_success_internal(void) +{ + struct wps_sm* sm = gWpsSm; + + system_event_t evt; + + wifi_config_t *config = (wifi_config_t *)os_zalloc(sizeof(wifi_config_t)); + memset(config, 0x00, sizeof(wifi_sta_config_t)); + memcpy(config->sta.ssid, sm->ssid[0], sm->ssid_len[0]); + memcpy(config->sta.password, sm->key[0], sm->key_len[0]); + memcpy(config->sta.bssid, sm->bssid, ETH_ALEN); + config->sta.bssid_set = 0; + esp_wifi_set_config(0, config); + + os_free(config); + config = NULL; + + evt.event_id = SYSTEM_EVENT_STA_WPS_ER_SUCCESS; + esp_event_send(&evt); +} + +void wifi_station_wps_success(void) +{ +#ifdef USE_WPS_TASK + wps_post(SIG_WPS_TIMER_SUCCESS_CB, 0); + return; +#else + wifi_station_wps_success_internal(); +#endif +} + +void wifi_station_wps_eapol_start_handle_internal(void) +{ + wpa_printf(MSG_DEBUG, "Resend EAPOL-Start."); + wps_tx_start(); +} + +void wifi_station_wps_eapol_start_handle(void) +{ +#ifdef USE_WPS_TASK + wps_post(SIG_WPS_TIMER_EAPOL_START, 0); + return; +#else + wifi_station_wps_eapol_start_handle_internal(); +#endif +} + +int +wifi_station_wps_init(void) +{ + struct wps_funcs *wps_cb; + struct wps_sm *sm = NULL; + uint8_t mac[6]; + + if (gWpsSm) { + goto _out; + } + + wpa_printf(MSG_DEBUG, "wifi sta wps init"); + + gWpsSm = (struct wps_sm *)os_zalloc(sizeof(struct wps_sm)); /* alloc Wps_sm */ + if (!gWpsSm) { + goto _err; + } + + sm = gWpsSm; + memset(sm, 0x00, sizeof(struct wps_sm)); + + esp_wifi_get_macaddr_internal(WIFI_IF_STA, mac); + memcpy(sm->ownaddr, mac, ETH_ALEN); + + sm->discover_ssid_cnt = 0; + sm->ignore_sel_reg = false; + sm->discard_ap_cnt = 0; + memset(&sm->dis_ap_list, 0, WPS_MAX_DIS_AP_NUM * sizeof(struct discard_ap_list_t)); + memset(&sm->config, 0x00, sizeof(wifi_sta_config_t)); + sm->eapol_version = 0x1; + sm->identity_len = 29; + memcpy(sm->identity, WPS_EAP_EXT_VENDOR_TYPE, sm->identity_len); + + sm->is_wps_scan = false; + + sm->wps_ctx = (struct wps_context *)os_zalloc(sizeof(struct wps_context)); /* alloc wps_ctx */ + if (!sm->wps_ctx) { + goto _err; + } + + if (wps_dev_init() != 0) { + goto _err; + } + + if ((sm->wps = wps_init()) == NULL) { /* alloc wps_data */ + goto _err; + } + + /**************80211 reference***************/ + + if (esp_wifi_get_appie_internal(WIFI_APPIE_WPS_PR) == NULL) { /* alloc probe req wps ie */ + wps_build_ic_appie_wps_pr(); + } + + if (esp_wifi_get_appie_internal(WIFI_APPIE_WPS_AR) == NULL) { /* alloc assoc req wps ie */ + wps_build_ic_appie_wps_ar(); + } + + ets_timer_disarm(&sm->wps_timeout_timer); + ets_timer_setfn(&sm->wps_timeout_timer, (ETSTimerFunc *)wifi_station_wps_timeout, NULL); + ets_timer_disarm(&sm->wps_msg_timeout_timer); + ets_timer_setfn(&sm->wps_msg_timeout_timer, (ETSTimerFunc *)wifi_station_wps_msg_timeout, NULL); + ets_timer_disarm(&sm->wps_success_cb_timer); + ets_timer_setfn(&sm->wps_success_cb_timer, (ETSTimerFunc *)wifi_station_wps_success, NULL); + ets_timer_disarm(&sm->wps_scan_timer); + ets_timer_setfn(&sm->wps_scan_timer, (ETSTimerFunc *)wifi_wps_scan, NULL); + ets_timer_disarm(&sm->wps_eapol_start_timer); + ets_timer_setfn(&sm->wps_eapol_start_timer, (ETSTimerFunc *)wifi_station_wps_eapol_start_handle, NULL); + + sm->scan_cnt = 0; + + wps_cb = os_malloc(sizeof(struct wps_funcs)); + if (wps_cb == NULL) { + goto _err; + } else { + wps_cb->wps_parse_scan_result = wps_parse_scan_result; + wps_cb->wifi_station_wps_start = wifi_station_wps_start; + wps_cb->wps_sm_rx_eapol = wps_sm_rx_eapol; + wps_cb->wps_start_pending = wps_start_pending; + esp_wifi_set_wps_cb_internal(wps_cb); + } + + return ESP_OK; + +_err: + esp_wifi_unset_appie_internal(WIFI_APPIE_WPS_PR); + esp_wifi_unset_appie_internal(WIFI_APPIE_WPS_AR); + + if (sm->dev) { + wps_dev_deinit(sm->dev); + sm->dev = NULL; + } + if (sm->wps_ctx) { + os_free(sm->wps_ctx); + sm->wps_ctx = NULL; + } + if (sm->wps) { + wps_deinit(); + sm->wps = NULL; + } + if (sm) { + os_free(gWpsSm); + gWpsSm = NULL; + } + return ESP_FAIL; +_out: + return ESP_FAIL; +} + +int wps_delete_timer(void) +{ + struct wps_sm *sm = gWpsSm; + + if (!sm) { + return ESP_OK; + } + + ets_timer_disarm(&sm->wps_success_cb_timer); + ets_timer_disarm(&sm->wps_timeout_timer); + ets_timer_disarm(&sm->wps_msg_timeout_timer); + ets_timer_disarm(&sm->wps_scan_timer); + ets_timer_disarm(&sm->wps_eapol_start_timer); + ets_timer_done(&sm->wps_success_cb_timer); + ets_timer_done(&sm->wps_timeout_timer); + ets_timer_done(&sm->wps_msg_timeout_timer); + ets_timer_done(&sm->wps_scan_timer); + ets_timer_done(&sm->wps_eapol_start_timer); + esp_wifi_disarm_sta_connection_timer_internal(); + return ESP_OK; +} + +int +wifi_station_wps_deinit(void) +{ + struct wps_sm *sm = gWpsSm; + + if (gWpsSm == NULL) { + return ESP_FAIL; + } + + esp_wifi_unset_appie_internal(WIFI_APPIE_WPS_PR); + esp_wifi_unset_appie_internal(WIFI_APPIE_WPS_AR); + esp_wifi_set_wps_cb_internal(NULL); + + if (sm->dev) { + wps_dev_deinit(sm->dev); + sm->dev = NULL; + } + if (sm->wps_ctx) { + os_free(sm->wps_ctx); + sm->wps_ctx = NULL; + } + if (sm->wps) { + wps_deinit(); + sm->wps = NULL; + } + if (sm) { + os_free(gWpsSm); + gWpsSm = NULL; + } + + return ESP_OK; +} + +int +wps_station_wps_register_cb(wps_st_cb_t cb) +{ + if (!gWpsSm) { + return ESP_FAIL; + } + + gWpsSm->st_cb = cb; + return ESP_OK; +} + +struct wps_sm * +wps_sm_get(void) +{ + return gWpsSm; +} + +int +wps_ssid_save(u8 *ssid, u8 ssid_len, u8 idx) +{ + u8 *tmpssid; + + if (!ssid || !gWpsSm || idx > 2) { + return ESP_FAIL; + } + + memset(gWpsSm->ssid[idx], 0x00, sizeof(gWpsSm->ssid[idx])); + memcpy(gWpsSm->ssid[idx], ssid, ssid_len); + gWpsSm->ssid_len[idx] = ssid_len; + gWpsSm->ap_cred_cnt++; + + tmpssid = (u8 *)os_zalloc(ssid_len + 1); + if (tmpssid) { + memcpy(tmpssid, ssid, ssid_len); + wpa_printf(MSG_DEBUG, "WPS: key[%s]", tmpssid); + os_free(tmpssid); + } + return ESP_OK; +} + +int +wps_key_save(char *key, u8 key_len, u8 idx) +{ + u8 *tmpkey; + + if (!key || !gWpsSm || idx > 2) { + return ESP_FAIL; + } + + memset(gWpsSm->key[idx], 0x00, sizeof(gWpsSm->key[idx])); + memcpy(gWpsSm->key[idx], key, key_len); + gWpsSm->key_len[idx] = key_len; + + tmpkey = (u8 *)os_zalloc(key_len + 1); + if (tmpkey) { + memcpy(tmpkey, key, key_len); + wpa_printf(MSG_DEBUG, "WPS: key[%s], idx - %d", tmpkey, idx); + os_free(tmpkey); + } + return ESP_OK; +} + +void +wifi_wps_scan_done(void *arg, STATUS status) +{ + struct wps_sm *sm = gWpsSm; + wifi_config_t wifi_config; + + if (wps_get_type() == WPS_TYPE_DISABLE) { + return; + } + + if (!sm) { + return; + } + + if (sm->discover_ssid_cnt == 1) { + wps_set_status(WPS_STATUS_PENDING); + } else if (sm->discover_ssid_cnt == 0) { + wps_set_status(WPS_STATUS_SCANNING); + } else { + wpa_printf(MSG_INFO, "PBC session overlap!"); + wps_set_status(WPS_STATUS_DISABLE); + } + + wpa_printf(MSG_DEBUG, "wps scan_done discover_ssid_cnt = %d", sm->discover_ssid_cnt); + + sm->discover_ssid_cnt = 0; + + if (wps_get_status() == WPS_STATUS_PENDING) { + esp_wifi_disconnect(); + + memcpy(&wifi_config.sta, &sm->config, sizeof(wifi_sta_config_t)); + esp_wifi_set_config(0, &wifi_config); + + wpa_printf(MSG_DEBUG, "WPS: neg start"); + esp_wifi_connect(); + } else if (wps_get_status() == WPS_STATUS_SCANNING) { + if (sm->scan_cnt < WPS_IGNORE_SEL_REG_MAX_CNT) { + sm->ignore_sel_reg = true; + } + ets_timer_arm(&sm->wps_scan_timer, 100, 0); + } else { + return; + } +} + +void +wifi_wps_scan_internal(void) +{ + struct wps_sm *sm = gWpsSm; + + sm->scan_cnt++; + wpa_printf(MSG_DEBUG, "wifi_wps_scan : %d", sm->scan_cnt); + + typedef void (* scan_done_cb_t)(void *arg, STATUS status); + extern int esp_wifi_promiscuous_scan_start(wifi_scan_config_t *config, scan_done_cb_t cb); + esp_wifi_promiscuous_scan_start(NULL, wifi_wps_scan_done); +} + +void wifi_wps_scan(void) +{ +#ifdef USE_WPS_TASK + wps_post(SIG_WPS_TIMER_SCAN, 0); + return; +#else + wifi_wps_scan_internal(); +#endif +} + +int wifi_station_wps_start(void) +{ + struct wps_sm *sm = wps_sm_get(); + + if (!sm) { + wpa_printf(MSG_ERROR, "WPS: wps not initial"); + return ESP_FAIL; + } + + ets_timer_arm(&sm->wps_timeout_timer, 120000, 0); /* 120s total */ + + switch (wps_get_status()) { + case WPS_STATUS_DISABLE: { + sm->is_wps_scan = true; + + wps_build_public_key(sm->wps, NULL, WPS_CALC_KEY_PRE_CALC); + + wifi_wps_scan(); + + + break; + } + case WPS_STATUS_SCANNING: + sm->scan_cnt = 0; + ets_timer_disarm(&sm->wps_timeout_timer); + ets_timer_arm(&sm->wps_timeout_timer, 120000, 0); /* 120s total */ + break; + default: + break; + } + esp_wifi_set_wps_start_flag_internal(true); + return ESP_OK; +} + +int wps_task_deinit(void) +{ + wpa_printf(MSG_DEBUG, "wps task deinit"); + + if (s_wps_api_sem) { + vSemaphoreDelete(s_wps_api_sem); + s_wps_api_sem = NULL; + wpa_printf(MSG_DEBUG, "wps task deinit: free api sem"); + } + + if (s_wps_task_create_sem) { + vSemaphoreDelete(s_wps_task_create_sem); + s_wps_task_create_sem = NULL; + wpa_printf(MSG_DEBUG, "wps task deinit: free task create sem"); + } + + if (s_wps_queue) { + vQueueDelete(s_wps_queue); + s_wps_queue = NULL; + wpa_printf(MSG_DEBUG, "wps task deinit: free queue"); + } + + if (s_wps_task_hdl) { + vTaskDelete(s_wps_task_hdl); + s_wps_task_hdl = NULL; + wpa_printf(MSG_DEBUG, "wps task deinit: free task"); + } + + if (STAILQ_FIRST(&s_wps_rxq) != NULL){ + wps_rxq_deinit(); + } + + if (s_wps_data_lock) { + vSemaphoreDelete(s_wps_data_lock); + s_wps_data_lock = NULL; + wpa_printf(MSG_DEBUG, "wps task deinit: free data lock"); + } + + return ESP_OK; +} + +int wps_task_init(void) +{ + int ret = 0; + + /* Call wps_task_deinit() first in case esp_wifi_wps_disable() fails + */ + wps_task_deinit(); + + s_wps_data_lock = xSemaphoreCreateRecursiveMutex(); + if (!s_wps_data_lock) { + wpa_printf(MSG_ERROR, "wps task init: failed to alloc data lock"); + goto _wps_no_mem; + } + + s_wps_api_sem = xSemaphoreCreateCounting(1, 0); + if (!s_wps_api_sem) { + wpa_printf(MSG_ERROR, "wps task init: failed to create api sem"); + goto _wps_no_mem; + } + + s_wps_task_create_sem = xSemaphoreCreateCounting(1, 0); + if (!s_wps_task_create_sem) { + wpa_printf(MSG_ERROR, "wps task init: failed to create task sem"); + goto _wps_no_mem; + } + + os_bzero(s_wps_sig_cnt, SIG_WPS_NUM); + s_wps_queue = xQueueCreate(SIG_WPS_NUM, sizeof( void * ) ); + if (!s_wps_queue) { + wpa_printf(MSG_ERROR, "wps task init: failed to alloc queue"); + goto _wps_no_mem; + } + + wps_rxq_init(); + + ret = xTaskCreate(wps_task, "wpsT", WPS_TASK_STACK_SIZE, NULL, 2, &s_wps_task_hdl); + if (pdPASS != ret) { + wpa_printf(MSG_ERROR, "wps enable: failed to create task"); + goto _wps_no_mem; + } + + xSemaphoreTake(s_wps_task_create_sem, portMAX_DELAY); + vSemaphoreDelete(s_wps_task_create_sem); + s_wps_task_create_sem = NULL; + + wpa_printf(MSG_DEBUG, "wifi wps enable: task prio:%d, stack:%d", 2, WPS_TASK_STACK_SIZE); + return ESP_OK; + +_wps_no_mem: + wps_task_deinit(); + return ESP_ERR_NO_MEM; +} + +int wps_post_block(uint32_t sig, void *arg) +{ + wps_ioctl_param_t param; + + param.ret = ESP_FAIL; + param.arg = arg; + + if (ESP_OK != wps_post(sig, (uint32_t)¶m)) { + return ESP_FAIL; + } + + if (pdPASS == xSemaphoreTake(s_wps_api_sem, portMAX_DELAY)) { + return param.ret; + } else { + return ESP_FAIL; + } +} + +int wps_check_wifi_mode(void) +{ + bool sniffer = false; + wifi_mode_t mode; + int ret; + + ret = esp_wifi_get_mode(&mode); + if (ESP_OK != ret) { + wpa_printf(MSG_ERROR, "wps check wifi mode: failed to get wifi mode ret=%d", ret); + return ESP_FAIL; + } + + ret = esp_wifi_get_promiscuous(&sniffer); + if (ESP_OK != ret) { + wpa_printf(MSG_ERROR, "wps check wifi mode: failed to get sniffer mode ret=%d", ret); + return ESP_FAIL; + } + + if (mode == WIFI_MODE_AP || mode == WIFI_MODE_NULL || sniffer == true) { + wpa_printf(MSG_ERROR, "wps check wifi mode: wrong wifi mode=%d sniffer=%d", mode, sniffer); + return ESP_ERR_WIFI_MODE; + } + + return ESP_OK; +} + +int esp_wifi_wps_enable(const esp_wps_config_t *config) +{ + int ret; + + if (ESP_OK != wps_check_wifi_mode()) { + return ESP_ERR_WIFI_MODE; + } + + API_MUTEX_TAKE(); + if (s_wps_enabled) { + API_MUTEX_GIVE(); + wpa_printf(MSG_DEBUG, "wps enable: already enabled"); + return ESP_OK; + } + +#ifdef USE_WPS_TASK + ret = wps_task_init(); + if (ESP_OK != ret) { + API_MUTEX_GIVE(); + return ret; + } + + ret = wps_post_block(SIG_WPS_ENABLE, (esp_wps_config_t *)config); + if (ESP_OK != ret) { + wps_task_deinit(); + API_MUTEX_GIVE(); + return ret; + } + + s_wps_enabled = true; + wpa_printf(MSG_DEBUG, "wifi wps task: prio:%d, stack:%d\n", 2, WPS_TASK_STACK_SIZE); + API_MUTEX_GIVE(); + return ret; +#else + ret = wifi_wps_enable_internal(config); + API_MUTEX_GIVE(); + return ret; +#endif +} + +int wifi_wps_enable_internal(const esp_wps_config_t *config) +{ + int ret = 0; + + wpa_printf(MSG_DEBUG, "ESP WPS crypto initialize!"); + if (config->wps_type == WPS_TYPE_DISABLE) { + wpa_printf(MSG_ERROR, "wps enable: invalid wps type"); + return ESP_ERR_WIFI_WPS_TYPE; + } + + /* currently , we don't support REGISTRAR */ + if (IS_WPS_REGISTRAR(config->wps_type)) { + wpa_printf(MSG_ERROR, "wps enable: not support registrar"); + return ESP_ERR_WIFI_WPS_TYPE; + } + + wpa_printf(MSG_DEBUG, "Set factory information."); + ret = wps_set_factory_info(config); + if (ret != 0) { + return ret; + } + + wpa_printf(MSG_INFO, "wifi_wps_enable\n"); + + wps_set_type(config->wps_type); + wps_set_status(WPS_STATUS_DISABLE); + + ret = wifi_station_wps_init(); + + if (ret != 0) { + wps_set_type(WPS_STATUS_DISABLE); + wps_set_status(WPS_STATUS_DISABLE); + return ESP_FAIL; + } + + return ESP_OK; +} + +int wifi_wps_disable_internal(void) +{ + wps_set_status(WPS_STATUS_DISABLE); + wifi_station_wps_deinit(); + return ESP_OK; +} + +int esp_wifi_wps_disable(void) +{ + int ret = 0; + + if (ESP_OK != wps_check_wifi_mode()) { + return ESP_ERR_WIFI_MODE; + } + + API_MUTEX_TAKE(); + + if (!s_wps_enabled) { + wpa_printf(MSG_DEBUG, "wps disable: already disabled"); + API_MUTEX_GIVE(); + return ESP_OK; + } + + wpa_printf(MSG_INFO, "wifi_wps_disable\n"); + wps_set_type(WPS_TYPE_DISABLE); /* Notify WiFi task */ + + /* Call wps_delete_timer to delete all WPS timer, no timer will call wps_post() + * to post message to wps_task once this function returns. + */ + wps_delete_timer(); + +#ifdef USE_WPS_TASK + ret = wps_post_block(SIG_WPS_DISABLE, 0); +#else + ret = wifi_wps_disable_internal(); +#endif + + if (ESP_OK != ret) { + wpa_printf(MSG_ERROR, "wps disable: failed to disable wps, ret=%d", ret); + } + + esp_wifi_disconnect(); + esp_wifi_set_wps_start_flag_internal(false); + wps_task_deinit(); + s_wps_enabled = false; + API_MUTEX_GIVE(); + return ESP_OK; +} + +int esp_wifi_wps_start(int timeout_ms) +{ + if (ESP_OK != wps_check_wifi_mode()) { + return ESP_ERR_WIFI_MODE; + } + + API_MUTEX_TAKE(); + + if (!s_wps_enabled) { + wpa_printf(MSG_ERROR, "wps start: wps not enabled"); + API_MUTEX_GIVE(); + return ESP_ERR_WIFI_WPS_SM; + } + + if (wps_get_type() == WPS_TYPE_DISABLE || (wps_get_status() != WPS_STATUS_DISABLE && wps_get_status() != WPS_STATUS_SCANNING)) { + API_MUTEX_GIVE(); + return ESP_ERR_WIFI_WPS_TYPE; + } + + if (esp_wifi_get_user_init_flag_internal() == 0) { + API_MUTEX_GIVE(); + return ESP_ERR_WIFI_STATE; + } + + wpa_printf(MSG_DEBUG, "wps scan"); + +#ifdef USE_WPS_TASK + wps_post_block(SIG_WPS_START, 0); +#else + ic_pp_post(SIG_PP_WPS, 0); +#endif + + API_MUTEX_GIVE(); + return ESP_OK; +} + +bool +wifi_set_wps_cb(wps_st_cb_t cb) +{ + wifi_mode_t mode; + + esp_wifi_get_mode(&mode); + if (mode == WIFI_MODE_AP || mode == WIFI_MODE_NULL) { + return false; + } + + if (wps_station_wps_register_cb(cb) == 0) { + return true; + } + + return false; +} + diff --git a/components/wpa_supplicant/src/fast_crypto/fast_aes-cbc.c b/components/wpa_supplicant/src/fast_crypto/fast_aes-cbc.c deleted file mode 100644 index 3d99c072..00000000 --- a/components/wpa_supplicant/src/fast_crypto/fast_aes-cbc.c +++ /dev/null @@ -1,82 +0,0 @@ -// Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); - -#include "sdkconfig.h" - -#include "utils/includes.h" -#include "utils/common.h" -#include "crypto/aes.h" -#include "crypto/aes_wrap.h" - -#if CONFIG_SSL_USING_MBEDTLS -#include "mbedtls/aes.h" - -/** - * fast_aes_128_cbc_encrypt - AES-128 CBC encryption - * @key: Encryption key - * @iv: Encryption IV for CBC mode (16 bytes) - * @data: Data to encrypt in-place - * @data_len: Length of data in bytes (must be divisible by 16) - * Returns: 0 on success, -1 on failure - */ -int -fast_aes_128_cbc_encrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data, size_t data_len) -{ - int ret = 0; - mbedtls_aes_context ctx; - uint8_t cbc[AES_BLOCK_SIZE]; - - mbedtls_aes_init(&ctx); - - ret = mbedtls_aes_setkey_enc(&ctx, key, 128); - - if(ret < 0) { - mbedtls_aes_free(&ctx); - return ret; - } - - os_memcpy(cbc, iv, AES_BLOCK_SIZE); - - ret = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, data_len, cbc, data, data); - - mbedtls_aes_free(&ctx); - - return ret; -} - - -/** - * fast_aes_128_cbc_decrypt - AES-128 CBC decryption - * @key: Decryption key - * @iv: Decryption IV for CBC mode (16 bytes) - * @data: Data to decrypt in-place - * @data_len: Length of data in bytes (must be divisible by 16) - * Returns: 0 on success, -1 on failure - */ -int -fast_aes_128_cbc_decrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data, size_t data_len) -{ - int ret = 0; - mbedtls_aes_context ctx; - uint8_t cbc[AES_BLOCK_SIZE]; - - mbedtls_aes_init(&ctx); - - ret = mbedtls_aes_setkey_dec(&ctx, key, 128); - - if(ret < 0) { - mbedtls_aes_free(&ctx); - return ret; - } - - os_memcpy(cbc, iv, AES_BLOCK_SIZE); - - ret = mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, data_len, cbc, data, data); - - mbedtls_aes_free(&ctx); - - return ret; - -} -#endif \ No newline at end of file diff --git a/components/wpa_supplicant/src/fast_crypto/fast_aes-unwrap.c b/components/wpa_supplicant/src/fast_crypto/fast_aes-unwrap.c deleted file mode 100644 index 88b40081..00000000 --- a/components/wpa_supplicant/src/fast_crypto/fast_aes-unwrap.c +++ /dev/null @@ -1,87 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#include "sdkconfig.h" - -#include "utils/includes.h" -#include "utils/common.h" - -#if CONFIG_SSL_USING_MBEDTLS -#include "mbedtls/aes.h" -/** - * fast_aes_unwrap - Unwrap key with AES Key Wrap Algorithm (128-bit KEK) (RFC3394) - * @kek: Key encryption key (KEK) - * @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16 - * bytes - * @cipher: Wrapped key to be unwrapped, (n + 1) * 64 bits - * @plain: Plaintext key, n * 64 bits - * Returns: 0 on success, -1 on failure (e.g., integrity verification failed) - */ -int -fast_aes_unwrap(const uint8_t *kek, int n, const uint8_t *cipher, uint8_t *plain) -{ - uint8_t a[8], *r, b[16]; - int32_t i, j; - int32_t ret = 0; - mbedtls_aes_context ctx; - - /* 1) Initialize variables. */ - os_memcpy(a, cipher, 8); - r = plain; - os_memcpy(r, cipher + 8, 8 * n); - - mbedtls_aes_init(&ctx); - ret = mbedtls_aes_setkey_dec(&ctx, kek, 128); - if (ret < 0) { - mbedtls_aes_free(&ctx); - return ret; - } - - /* 2) Compute intermediate values. - * For j = 5 to 0 - * For i = n to 1 - * B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i - * A = MSB(64, B) - * R[i] = LSB(64, B) - */ - for (j = 5; j >= 0; j--) { - r = plain + (n - 1) * 8; - for (i = n; i >= 1; i--) { - os_memcpy(b, a, 8); - b[7] ^= n * j + i; - os_memcpy(b + 8, r, 8); - ret = mbedtls_internal_aes_decrypt(&ctx, b, b); - if (ret != 0) { - break; - } - os_memcpy(a, b, 8); - os_memcpy(r, b + 8, 8); - r -= 8; - } - } - mbedtls_aes_free(&ctx); - - /* 3) Output results. - * - * These are already in @plain due to the location of temporary - * variables. Just verify that the IV matches with the expected value. - */ - for (i = 0; i < 8; i++) { - if (a[i] != 0xa6) { - return -1; - } - } - - return ret; -} -#endif \ No newline at end of file diff --git a/components/wpa_supplicant/src/fast_crypto/fast_aes-wrap.c b/components/wpa_supplicant/src/fast_crypto/fast_aes-wrap.c deleted file mode 100644 index 8ab6bc28..00000000 --- a/components/wpa_supplicant/src/fast_crypto/fast_aes-wrap.c +++ /dev/null @@ -1,88 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "sdkconfig.h" - -#include "utils/includes.h" - -#include "utils/common.h" -#include "crypto/aes.h" -#include "crypto/aes_wrap.h" - -#if CONFIG_SSL_USING_MBEDTLS -#include "mbedtls/aes.h" - -/** - * fast_aes_wrap - Wrap keys with AES Key Wrap Algorithm (128-bit KEK) (RFC3394) - * @kek: 16-octet Key encryption key (KEK) - * @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16 - * bytes - * @plain: Plaintext key to be wrapped, n * 64 bits - * @cipher: Wrapped key, (n + 1) * 64 bits - * Returns: 0 on success, -1 on failure - */ -int fast_aes_wrap(const uint8_t *kek, int n, const uint8_t *plain, uint8_t *cipher) -{ - uint8_t *a, *r, b[16]; - int32_t i, j; - int32_t ret = 0; - mbedtls_aes_context ctx; - - a = cipher; - r = cipher + 8; - - /* 1) Initialize variables. */ - os_memset(a, 0xa6, 8); - os_memcpy(r, plain, 8 * n); - - mbedtls_aes_init(&ctx); - ret = mbedtls_aes_setkey_enc(&ctx, kek, 128); - if (ret < 0) { - mbedtls_aes_free(&ctx); - return ret; - } - - /* 2) Calculate intermediate values. - * For j = 0 to 5 - * For i=1 to n - * B = AES(K, A | R[i]) - * A = MSB(64, B) ^ t where t = (n*j)+i - * R[i] = LSB(64, B) - */ - for (j = 0; j <= 5; j++) { - r = cipher + 8; - for (i = 1; i <= n; i++) { - os_memcpy(b, a, 8); - os_memcpy(b + 8, r, 8); - ret = mbedtls_internal_aes_encrypt(&ctx, b, b); - if (ret != 0) { - break; - } - os_memcpy(a, b, 8); - a[7] ^= n * j + i; - os_memcpy(r, b + 8, 8); - r += 8; - } - } - mbedtls_aes_free(&ctx); - - /* 3) Output the results. - * - * These are already in @cipher due to the location of temporary - * variables. - */ - - return ret; -} -#endif \ No newline at end of file diff --git a/components/wpa_supplicant/src/fast_crypto/fast_crypto_internal-cipher.c b/components/wpa_supplicant/src/fast_crypto/fast_crypto_internal-cipher.c deleted file mode 100644 index 0474c3fd..00000000 --- a/components/wpa_supplicant/src/fast_crypto/fast_crypto_internal-cipher.c +++ /dev/null @@ -1,290 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//#include "utils/includes.h" -#include "sdkconfig.h" - -#include "utils/common.h" -#include "crypto/crypto.h" -#include "crypto/aes.h" -#if defined(CONFIG_DES) || defined(CONFIG_DES3) -#include "crypto/des_i.h" -#endif - -#if CONFIG_SSL_USING_MBEDTLS -#include "mbedtls/aes.h" - -struct fast_crypto_cipher { - enum crypto_cipher_alg alg; - union { - struct { - size_t used_bytes; - uint8_t key[16]; - size_t keylen; - } rc4; - struct { - uint8_t cbc[32]; - mbedtls_aes_context ctx_enc; - mbedtls_aes_context ctx_dec; - } aes; -#ifdef CONFIG_DES3 - struct { - struct des3_key_s key; - uint8_t cbc[8]; - } des3; -#endif -#ifdef CONFIG_DES - struct { - uint32_t ek[32]; - uint32_t dk[32]; - uint32_t cbc[8]; - } des; -#endif - } u; -}; - - -struct crypto_cipher * fast_crypto_cipher_init(enum crypto_cipher_alg alg, - const uint8_t *iv, const uint8_t *key, - size_t key_len) -{ - struct fast_crypto_cipher *ctx; - - ctx = (struct fast_crypto_cipher *)os_zalloc(sizeof(*ctx)); - if (ctx == NULL) { - return NULL; - } - - ctx->alg = alg; - - switch (alg) { - case CRYPTO_CIPHER_ALG_RC4: - if (key_len > sizeof(ctx->u.rc4.key)) { - os_free(ctx); - return NULL; - } - ctx->u.rc4.keylen = key_len; - os_memcpy(ctx->u.rc4.key, key, key_len); - break; - case CRYPTO_CIPHER_ALG_AES: - mbedtls_aes_init(&(ctx->u.aes.ctx_enc)); - mbedtls_aes_setkey_enc(&(ctx->u.aes.ctx_enc), key, key_len * 8); - mbedtls_aes_init(&(ctx->u.aes.ctx_dec)); - mbedtls_aes_setkey_dec(&(ctx->u.aes.ctx_dec), key, key_len * 8); - os_memcpy(ctx->u.aes.cbc, iv, AES_BLOCK_SIZE); - break; -#ifdef CONFIG_DES3 - case CRYPTO_CIPHER_ALG_3DES: - if (key_len != 24) { - os_free(ctx); - return NULL; - } - des3_key_setup(key, &ctx->u.des3.key); - os_memcpy(ctx->u.des3.cbc, iv, 8); - break; -#endif -#ifdef CONFIG_DES - case CRYPTO_CIPHER_ALG_DES: - if (key_len != 8) { - os_free(ctx); - return NULL; - } - des_key_setup(key, ctx->u.des.ek, ctx->u.des.dk); - os_memcpy(ctx->u.des.cbc, iv, 8); - break; -#endif - default: - os_free(ctx); - return NULL; - } - - return (struct crypto_cipher *)ctx; -} - - -int fast_crypto_cipher_encrypt(struct crypto_cipher *ctx, const uint8_t *plain, - uint8_t *crypt, size_t len) -{ - size_t i, j, blocks; - struct fast_crypto_cipher *fast_ctx; - - fast_ctx = (struct fast_crypto_cipher *)ctx; - - switch (fast_ctx->alg) { - case CRYPTO_CIPHER_ALG_RC4: - if (plain != crypt) { - os_memcpy(crypt, plain, len); - } - rc4_skip(fast_ctx->u.rc4.key, fast_ctx->u.rc4.keylen, - fast_ctx->u.rc4.used_bytes, crypt, len); - fast_ctx->u.rc4.used_bytes += len; - break; - case CRYPTO_CIPHER_ALG_AES: - if (len % AES_BLOCK_SIZE) { - return -1; - } - blocks = len / AES_BLOCK_SIZE; - for (i = 0; i < blocks; i++) { - for (j = 0; j < AES_BLOCK_SIZE; j++) - fast_ctx->u.aes.cbc[j] ^= plain[j]; - if (mbedtls_internal_aes_encrypt(&(fast_ctx->u.aes.ctx_enc), fast_ctx->u.aes.cbc, fast_ctx->u.aes.cbc) != 0) { - return -1; - } - os_memcpy(crypt, fast_ctx->u.aes.cbc, AES_BLOCK_SIZE); - plain += AES_BLOCK_SIZE; - crypt += AES_BLOCK_SIZE; - } - break; -#ifdef CONFIG_DES3 - case CRYPTO_CIPHER_ALG_3DES: - if (len % 8) { - return -1; - } - blocks = len / 8; - for (i = 0; i < blocks; i++) { - for (j = 0; j < 8; j++) - fast_ctx->u.des3.cbc[j] ^= plain[j]; - des3_encrypt(fast_ctx->u.des3.cbc, &fast_ctx->u.des3.key, - fast_ctx->u.des3.cbc); - os_memcpy(crypt, fast_ctx->u.des3.cbc, 8); - plain += 8; - crypt += 8; - } - break; -#endif -#ifdef CONFIG_DES - case CRYPTO_CIPHER_ALG_DES: - if (len % 8) { - return -1; - } - blocks = len / 8; - for (i = 0; i < blocks; i++) { - for (j = 0; j < 8; j++) - fast_ctx->u.des3.cbc[j] ^= plain[j]; - des_block_encrypt(fast_ctx->u.des.cbc, fast_ctx->u.des.ek, - fast_ctx->u.des.cbc); - os_memcpy(crypt, fast_ctx->u.des.cbc, 8); - plain += 8; - crypt += 8; - } - break; -#endif - default: - return -1; - } - - return 0; -} - - -int fast_crypto_cipher_decrypt(struct crypto_cipher *ctx, const uint8_t *crypt, - uint8_t *plain, size_t len) -{ - size_t i, j, blocks; - uint8_t tmp[32]; - struct fast_crypto_cipher *fast_ctx; - - fast_ctx = (struct fast_crypto_cipher *)ctx; - - switch (fast_ctx->alg) { - case CRYPTO_CIPHER_ALG_RC4: - if (plain != crypt) { - os_memcpy(plain, crypt, len); - } - rc4_skip(fast_ctx->u.rc4.key, fast_ctx->u.rc4.keylen, - fast_ctx->u.rc4.used_bytes, plain, len); - fast_ctx->u.rc4.used_bytes += len; - break; - case CRYPTO_CIPHER_ALG_AES: - if (len % AES_BLOCK_SIZE) { - return -1; - } - blocks = len / AES_BLOCK_SIZE; - for (i = 0; i < blocks; i++) { - os_memcpy(tmp, crypt, AES_BLOCK_SIZE); - if (mbedtls_internal_aes_decrypt(&(fast_ctx->u.aes.ctx_dec), crypt, plain) != 0) { - return -1; - } - for (j = 0; j < AES_BLOCK_SIZE; j++) - plain[j] ^= fast_ctx->u.aes.cbc[j]; - os_memcpy(fast_ctx->u.aes.cbc, tmp, AES_BLOCK_SIZE); - plain += AES_BLOCK_SIZE; - crypt += AES_BLOCK_SIZE; - } - break; -#ifdef CONFIG_DES3 - case CRYPTO_CIPHER_ALG_3DES: - if (len % 8) { - return -1; - } - blocks = len / 8; - for (i = 0; i < blocks; i++) { - os_memcpy(tmp, crypt, 8); - des3_decrypt(crypt, &fast_ctx->u.des3.key, plain); - for (j = 0; j < 8; j++) { - plain[j] ^= fast_ctx->u.des3.cbc[j]; - } - os_memcpy(fast_ctx->u.des3.cbc, tmp, 8); - plain += 8; - crypt += 8; - } - break; -#endif -#ifdef CONFIG_DES - case CRYPTO_CIPHER_ALG_DES: - if (len % 8) { - return -1; - } - blocks = len / 8; - for (i = 0; i < blocks; i++) { - os_memcpy(tmp, crypt, 8); - des_block_decrypt(crypt, fast_ctx->u.des.dk, plain); - for (j = 0; j < 8; j++) { - plain[j] ^= fast_ctx->u.des.cbc[j]; - } - os_memcpy(fast_ctx->u.des.cbc, tmp, 8); - plain += 8; - crypt += 8; - } - break; -#endif - default: - return -1; -} - -return 0; -} - - -void fast_crypto_cipher_deinit(struct crypto_cipher *ctx) -{ - struct fast_crypto_cipher *fast_ctx; - - fast_ctx = (struct fast_crypto_cipher *)ctx; - - switch (fast_ctx->alg) { - case CRYPTO_CIPHER_ALG_AES: - mbedtls_aes_free(&(fast_ctx->u.aes.ctx_enc)); - mbedtls_aes_free(&(fast_ctx->u.aes.ctx_dec)); - break; -#ifdef CONFIG_DES3 - case CRYPTO_CIPHER_ALG_3DES: - break; -#endif - default: - break; - } - os_free(ctx); -} -#endif \ No newline at end of file diff --git a/components/wpa_supplicant/src/fast_crypto/fast_crypto_internal-modexp.c b/components/wpa_supplicant/src/fast_crypto/fast_crypto_internal-modexp.c deleted file mode 100644 index 59c8fe6b..00000000 --- a/components/wpa_supplicant/src/fast_crypto/fast_crypto_internal-modexp.c +++ /dev/null @@ -1,64 +0,0 @@ -// Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "sdkconfig.h" - -#include "utils/includes.h" - -#include "utils/common.h" -#include "crypto/crypto.h" - -#if CONFIG_SSL_USING_MBEDTLS -#include "mbedtls/bignum.h" - -int fast_crypto_mod_exp(const uint8_t *base, size_t base_len, - const uint8_t *power, size_t power_len, - const uint8_t *modulus, size_t modulus_len, - uint8_t *result, size_t *result_len) -{ - mbedtls_mpi bn_base, bn_exp, bn_modulus, bn_result, bn_rinv; - int32_t ret = 0; - mbedtls_mpi_init(&bn_base); - mbedtls_mpi_init(&bn_exp); - mbedtls_mpi_init(&bn_modulus); - mbedtls_mpi_init(&bn_result); - mbedtls_mpi_init(&bn_rinv); - - mbedtls_mpi_read_binary(&bn_base, base, base_len); - mbedtls_mpi_read_binary(&bn_exp, power, power_len); - mbedtls_mpi_read_binary(&bn_modulus, modulus, modulus_len); - - ret = mbedtls_mpi_exp_mod(&bn_result, &bn_base, &bn_exp, &bn_modulus, &bn_rinv); - - if (ret < 0) { - mbedtls_mpi_free(&bn_base); - mbedtls_mpi_free(&bn_exp); - mbedtls_mpi_free(&bn_modulus); - mbedtls_mpi_free(&bn_result); - mbedtls_mpi_free(&bn_rinv); - return ret; - } - - ret = mbedtls_mpi_write_binary(&bn_result, result, *result_len); - - - mbedtls_mpi_free(&bn_base); - mbedtls_mpi_free(&bn_exp); - mbedtls_mpi_free(&bn_modulus); - mbedtls_mpi_free(&bn_result); - mbedtls_mpi_free(&bn_rinv); - - return ret; -} -#endif \ No newline at end of file diff --git a/components/wpa_supplicant/src/fast_crypto/fast_crypto_internal.c b/components/wpa_supplicant/src/fast_crypto/fast_crypto_internal.c deleted file mode 100644 index 56084fe6..00000000 --- a/components/wpa_supplicant/src/fast_crypto/fast_crypto_internal.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Crypto wrapper for internal crypto implementation - * Copyright (c) 2006-2011, Jouni Malinen - * - * Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD - * - * This software may be distributed under the terms of the BSD license. - * See README for more details. - */ -#include "sdkconfig.h" - -#include "utils/includes.h" -#include "utils/common.h" -#include "crypto/crypto.h" -#include "crypto/sha1_i.h" -#include "crypto/md5_i.h" - -#if CONFIG_SSL_USING_MBEDTLS -#include "mbedtls/sha256.h" - - -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; -#endif - -struct fast_crypto_hash { - enum crypto_hash_alg alg; - union { - struct MD5Context md5; -#ifndef CONFIG_ESP_SHA - struct SHA1Context sha1; -#else - SHA1_CTX sha1; -#endif -#ifdef CONFIG_SHA256 - mbedtls_sha256_context sha256; -#endif /* CONFIG_SHA256 */ - } u; - u8 key[64]; - size_t key_len; -}; - -struct crypto_hash* fast_crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, - size_t key_len) -{ - struct fast_crypto_hash *ctx; - u8 k_pad[64]; - u8 tk[32]; - size_t i; - - ctx = (struct fast_crypto_hash *)os_zalloc(sizeof(*ctx)); - if (ctx == NULL) - return NULL; - - ctx->alg = alg; - - switch (alg) { - case CRYPTO_HASH_ALG_MD5: - MD5Init(&ctx->u.md5); - break; - case CRYPTO_HASH_ALG_SHA1: - SHA1Init(&ctx->u.sha1); - break; -#ifdef CONFIG_SHA256 - case CRYPTO_HASH_ALG_SHA256: - mbedtls_sha256_init(&ctx->u.sha256); - mbedtls_sha256_starts(&ctx->u.sha256, 0); - break; -#endif /* CONFIG_SHA256 */ - case CRYPTO_HASH_ALG_HMAC_MD5: - if (key_len > sizeof(k_pad)) { - MD5Init(&ctx->u.md5); - MD5Update(&ctx->u.md5, key, key_len); - MD5Final(tk, &ctx->u.md5); - key = tk; - key_len = 16; - } - os_memcpy(ctx->key, key, key_len); - ctx->key_len = key_len; - - os_memcpy(k_pad, key, key_len); - if (key_len < sizeof(k_pad)) - os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len); - for (i = 0; i < sizeof(k_pad); i++) - k_pad[i] ^= 0x36; - MD5Init(&ctx->u.md5); - MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad)); - break; - case CRYPTO_HASH_ALG_HMAC_SHA1: - if (key_len > sizeof(k_pad)) { - SHA1Init(&ctx->u.sha1); - SHA1Update(&ctx->u.sha1, key, key_len); - SHA1Final(tk, &ctx->u.sha1); - key = tk; - key_len = 20; - } - os_memcpy(ctx->key, key, key_len); - ctx->key_len = key_len; - - os_memcpy(k_pad, key, key_len); - if (key_len < sizeof(k_pad)) - os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len); - for (i = 0; i < sizeof(k_pad); i++) - k_pad[i] ^= 0x36; - SHA1Init(&ctx->u.sha1); - SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad)); - break; -#ifdef CONFIG_SHA256 - case CRYPTO_HASH_ALG_HMAC_SHA256: - if (key_len > sizeof(k_pad)) { - mbedtls_sha256_init(&ctx->u.sha256); - mbedtls_sha256_starts(&ctx->u.sha256, 0); - mbedtls_sha256_update(&ctx->u.sha256, key, key_len); - mbedtls_sha256_finish(&ctx->u.sha256, tk); - mbedtls_sha256_free(&ctx->u.sha256); - key = tk; - key_len = 32; - } - os_memcpy(ctx->key, key, key_len); - ctx->key_len = key_len; - - os_memcpy(k_pad, key, key_len); - if (key_len < sizeof(k_pad)) - os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len); - for (i = 0; i < sizeof(k_pad); i++) - k_pad[i] ^= 0x36; - mbedtls_sha256_init(&ctx->u.sha256); - mbedtls_sha256_starts(&ctx->u.sha256, 0); - mbedtls_sha256_update(&ctx->u.sha256, k_pad, sizeof(k_pad)); - break; -#endif /* CONFIG_SHA256 */ - default: - os_free(ctx); - return NULL; - } - - return (struct crypto_hash *)ctx; -} - - -void fast_crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len) -{ - - struct fast_crypto_hash *fast_ctx; - fast_ctx = (struct fast_crypto_hash *)ctx; - - if (fast_ctx == NULL) - return; - - switch (fast_ctx->alg) { - case CRYPTO_HASH_ALG_MD5: - case CRYPTO_HASH_ALG_HMAC_MD5: - MD5Update(&fast_ctx->u.md5, data, len); - break; - case CRYPTO_HASH_ALG_SHA1: - case CRYPTO_HASH_ALG_HMAC_SHA1: - SHA1Update(&fast_ctx->u.sha1, data, len); - break; -#ifdef CONFIG_SHA256 - case CRYPTO_HASH_ALG_SHA256: - case CRYPTO_HASH_ALG_HMAC_SHA256: - mbedtls_sha256_update(&fast_ctx->u.sha256, data, len); - break; -#endif /* CONFIG_SHA256 */ - default: - break; - } -} - -int fast_crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) -{ - u8 k_pad[64]; - size_t i; - struct fast_crypto_hash *fast_ctx; - - if (ctx == NULL) - return -2; - - fast_ctx = (struct fast_crypto_hash *)ctx; - - if (mac == NULL || len == NULL) { - os_free(fast_ctx); - return 0; - } - - switch (fast_ctx->alg) { - case CRYPTO_HASH_ALG_MD5: - if (*len < 16) { - *len = 16; - os_free(fast_ctx); - return -1; - } - *len = 16; - MD5Final(mac, &fast_ctx->u.md5); - break; - case CRYPTO_HASH_ALG_SHA1: - if (*len < 20) { - *len = 20; - os_free(fast_ctx); - return -1; - } - *len = 20; - SHA1Final(mac, &fast_ctx->u.sha1); - break; -#ifdef CONFIG_SHA256 - case CRYPTO_HASH_ALG_SHA256: - if (*len < 32) { - *len = 32; - os_free(fast_ctx); - return -1; - } - *len = 32; - mbedtls_sha256_finish(&fast_ctx->u.sha256, mac); - mbedtls_sha256_free(&fast_ctx->u.sha256); - break; -#endif /* CONFIG_SHA256 */ - case CRYPTO_HASH_ALG_HMAC_MD5: - if (*len < 16) { - *len = 16; - os_free(fast_ctx); - return -1; - } - *len = 16; - - MD5Final(mac, &fast_ctx->u.md5); - - os_memcpy(k_pad, fast_ctx->key, fast_ctx->key_len); - os_memset(k_pad + fast_ctx->key_len, 0, - sizeof(k_pad) - fast_ctx->key_len); - for (i = 0; i < sizeof(k_pad); i++) - k_pad[i] ^= 0x5c; - MD5Init(&fast_ctx->u.md5); - MD5Update(&fast_ctx->u.md5, k_pad, sizeof(k_pad)); - MD5Update(&fast_ctx->u.md5, mac, 16); - MD5Final(mac, &fast_ctx->u.md5); - break; - case CRYPTO_HASH_ALG_HMAC_SHA1: - if (*len < 20) { - *len = 20; - os_free(ctx); - return -1; - } - *len = 20; - - SHA1Final(mac, &fast_ctx->u.sha1); - os_memcpy(k_pad, fast_ctx->key, fast_ctx->key_len); - os_memset(k_pad + fast_ctx->key_len, 0, - sizeof(k_pad) - fast_ctx->key_len); - for (i = 0; i < sizeof(k_pad); i++) - k_pad[i] ^= 0x5c; - SHA1Init(&fast_ctx->u.sha1); - SHA1Update(&fast_ctx->u.sha1, k_pad, sizeof(k_pad)); - SHA1Update(&fast_ctx->u.sha1, mac, 20); - SHA1Final(mac, &fast_ctx->u.sha1); - break; -#ifdef CONFIG_SHA256 - case CRYPTO_HASH_ALG_HMAC_SHA256: - if (*len < 32) { - *len = 32; - os_free(fast_ctx); - return -1; - } - *len = 32; - mbedtls_sha256_finish(&fast_ctx->u.sha256, mac); - mbedtls_sha256_free(&fast_ctx->u.sha256); - - os_memcpy(k_pad, fast_ctx->key, fast_ctx->key_len); - os_memset(k_pad + fast_ctx->key_len, 0, - sizeof(k_pad) - fast_ctx->key_len); - for (i = 0; i < sizeof(k_pad); i++) - k_pad[i] ^= 0x5c; - mbedtls_sha256_init(&fast_ctx->u.sha256); - mbedtls_sha256_starts(&fast_ctx->u.sha256, 0); - mbedtls_sha256_update(&fast_ctx->u.sha256, k_pad, sizeof(k_pad)); - mbedtls_sha256_update(&fast_ctx->u.sha256, mac, 32); - mbedtls_sha256_finish(&fast_ctx->u.sha256, mac); - mbedtls_sha256_free(&fast_ctx->u.sha256); - break; -#endif /* CONFIG_SHA256 */ - default: - os_free(fast_ctx); - return -1; - } - - os_free(fast_ctx); - - return 0; -} -#endif \ No newline at end of file diff --git a/components/wpa_supplicant/src/fast_crypto/fast_crypto_ops.c b/components/wpa_supplicant/src/fast_crypto/fast_crypto_ops.c deleted file mode 100644 index e4576bda..00000000 --- a/components/wpa_supplicant/src/fast_crypto/fast_crypto_ops.c +++ /dev/null @@ -1,253 +0,0 @@ -// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "sdkconfig.h" - -#include "utils/common.h" -#include "crypto/aes_wrap.h" -#include "crypto/sha256.h" -#include "crypto/crypto.h" -#include "crypto/md5.h" -#include "crypto/sha1.h" -#include "crypto/aes.h" -#include "crypto/dh_group5.h" -#include "wps/wps.h" -#include "wps/wps_i.h" - -#include "eap_peer/eap.h" -#include "tls/tls.h" -#include "eap_peer/eap_methods.h" -#include "eap_peer/eap_i.h" -#include "eap_peer/eap_common.h" -#include "esp_wifi_crypto_types.h" - -int fast_sha256_vector(size_t num_elem, const uint8_t *addr[], const size_t *len, - uint8_t *mac); -int __must_check fast_aes_wrap(const uint8_t *kek, int n, const uint8_t *plain, uint8_t *cipher); -int __must_check fast_aes_unwrap(const uint8_t *kek, int n, const uint8_t *cipher, uint8_t *plain); -int __must_check fast_aes_128_cbc_encrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data, - size_t data_len); -int __must_check fast_aes_128_cbc_decrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data, - size_t data_len); -void fast_hmac_sha256_vector(const uint8_t *key, size_t key_len, size_t num_elem, - const uint8_t *addr[], const size_t *len, uint8_t *mac); -void fast_hmac_sha256(const uint8_t *key, size_t key_len, const uint8_t *data, - size_t data_len, uint8_t *mac); -void fast_sha256_prf(const uint8_t *key, size_t key_len, const char *label, - const uint8_t *data, size_t data_len, uint8_t *buf, size_t buf_len); -int __must_check fast_aes_wrap(const uint8_t *kek, int n, const uint8_t *plain, uint8_t *cipher); -int __must_check fast_aes_unwrap(const uint8_t *kek, int n, const uint8_t *cipher, uint8_t *plain); -int __must_check fast_aes_128_cbc_encrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data, - size_t data_len); -int __must_check fast_aes_128_cbc_decrypt(const uint8_t *key, const uint8_t *iv, uint8_t *data, - size_t data_len); -int __must_check crypto_mod_exp(const u8 *base, size_t base_len, - const u8 *power, size_t power_len, - const u8 *modulus, size_t modulus_len, - u8 *result, size_t *result_len); -void fast_crypto_hash_update(struct crypto_hash *ctx, const uint8_t *data, size_t len); -int fast_crypto_hash_finish(struct crypto_hash *ctx, uint8_t *hash, size_t *len); -struct crypto_cipher * fast_crypto_cipher_init(enum crypto_cipher_alg alg, - const uint8_t *iv, const uint8_t *key, - size_t key_len); -int __must_check fast_crypto_cipher_decrypt(struct crypto_cipher *ctx, - const uint8_t *crypt, uint8_t *plain, size_t len); -void fast_crypto_cipher_deinit(struct crypto_cipher *ctx); -int __must_check fast_crypto_mod_exp(const uint8_t *base, size_t base_len, - const uint8_t *power, size_t power_len, - const uint8_t *modulus, size_t modulus_len, - uint8_t *result, size_t *result_len); -struct crypto_hash * fast_crypto_hash_init(enum crypto_hash_alg alg, const uint8_t *key, - size_t key_len); -int __must_check fast_crypto_cipher_encrypt(struct crypto_cipher *ctx, - const uint8_t *plain, uint8_t *crypt, size_t len); - -#if CONFIG_SSL_USING_MBEDTLS -/* - * The parameters is used to set the cyrpto callback function for station connect when in security mode, - * every callback function can register as fast_xxx or normal one, i.e, fast_aes_wrap or aes_wrap, the - * difference between them is the normal API is calculate by software, the fast one use the hardware - * crypto in it, can be faster than the normal one, so the callback function register in default is which - * we recommend, so as the API in WPS default and WPA2 default. - */ -const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs = { - .size = sizeof(wpa_crypto_funcs_t), - .version = ESP_WIFI_CRYPTO_VERSION, - .aes_wrap = (esp_aes_wrap_t)fast_aes_wrap, - .aes_unwrap = (esp_aes_unwrap_t)fast_aes_unwrap, - .hmac_sha256_vector = (esp_hmac_sha256_vector_t)fast_hmac_sha256_vector, - .sha256_prf = (esp_sha256_prf_t)fast_sha256_prf, - .hmac_md5 = (esp_hmac_md5_t)hmac_md5, - .hamc_md5_vector = (esp_hmac_md5_vector_t)hmac_md5_vector, - .hmac_sha1 = (esp_hmac_sha1_t)hmac_sha1, - .hmac_sha1_vector = (esp_hmac_sha1_vector_t)hmac_sha1_vector, - .sha1_prf = (esp_sha1_prf_t)sha1_prf, - .sha1_vector = (esp_sha1_vector_t)sha1_vector, - .pbkdf2_sha1 = (esp_pbkdf2_sha1_t)pbkdf2_sha1, - .rc4_skip = (esp_rc4_skip_t)rc4_skip, - .md5_vector = (esp_md5_vector_t)md5_vector, - .aes_encrypt = (esp_aes_encrypt_t)aes_encrypt, - .aes_encrypt_init = (esp_aes_encrypt_init_t)aes_encrypt_init, - .aes_encrypt_deinit = (esp_aes_encrypt_deinit_t)aes_encrypt_deinit, - .aes_decrypt = (esp_aes_decrypt_t)aes_decrypt, - .aes_decrypt_init = (esp_aes_decrypt_init_t)aes_decrypt_init, - .aes_decrypt_deinit = (esp_aes_decrypt_deinit_t)aes_decrypt_deinit -}; - -const wps_crypto_funcs_t g_wifi_default_wps_crypto_funcs = { - .size = sizeof(wps_crypto_funcs_t), - .version = ESP_WIFI_CRYPTO_VERSION, - .aes_128_encrypt = (esp_aes_128_encrypt_t)fast_aes_128_cbc_encrypt, - .aes_128_decrypt = (esp_aes_128_decrypt_t)fast_aes_128_cbc_decrypt, - .crypto_mod_exp = (esp_crypto_mod_exp_t)fast_crypto_mod_exp, - .hmac_sha256 = (esp_hmac_sha256_t)fast_hmac_sha256, - .hmac_sha256_vector = (esp_hmac_sha256_vector_t)fast_hmac_sha256_vector, - .sha256_vector = (esp_sha256_vector_t)fast_sha256_vector, - .uuid_gen_mac_addr = (esp_uuid_gen_mac_addr_t)uuid_gen_mac_addr, - .dh5_free = (esp_dh5_free_t)dh5_free, - .wps_build_assoc_req_ie = (esp_wps_build_assoc_req_ie_t)wps_build_assoc_req_ie, - .wps_build_assoc_resp_ie = (esp_wps_build_assoc_resp_ie_t)wps_build_assoc_resp_ie, - .wps_build_probe_req_ie = (esp_wps_build_probe_req_ie_t)wps_build_probe_req_ie, - .wps_build_public_key = (esp_wps_build_public_key_t)wps_build_public_key, - .wps_enrollee_get_msg = (esp_wps_enrollee_get_msg_t)wps_enrollee_get_msg, - .wps_enrollee_process_msg = (esp_wps_enrollee_process_msg_t)wps_enrollee_process_msg, - .wps_generate_pin = (esp_wps_generate_pin_t)wps_generate_pin, - .wps_is_selected_pin_registrar = (esp_wps_is_selected_pin_registrar_t)wps_is_selected_pin_registrar, - .wps_is_selected_pbc_registrar = (esp_wps_is_selected_pbc_registrar_t)wps_is_selected_pbc_registrar, - .eap_msg_alloc = (esp_eap_msg_alloc_t)eap_msg_alloc -}; - -/* - * What should notice is that the cyrpto hash type function and crypto cipher type function can not register - * as different, i.e, if you use fast_crypto_hash_init, you should use fast_crypto_hash_update and - * fast_crypto_hash_finish for finish hash calculate, rather than call crypto_hash_update and - * crypto_hash_finish, so do crypto_cipher. - */ -const wpa2_crypto_funcs_t g_wifi_default_wpa2_crypto_funcs = { - .size = sizeof(wpa2_crypto_funcs_t), - .version = ESP_WIFI_CRYPTO_VERSION, - .crypto_hash_init = (esp_crypto_hash_init_t)fast_crypto_hash_init, - .crypto_hash_update = (esp_crypto_hash_update_t)fast_crypto_hash_update, - .crypto_hash_finish = (esp_crypto_hash_finish_t)fast_crypto_hash_finish, - .crypto_cipher_init = (esp_crypto_cipher_init_t)fast_crypto_cipher_init, - .crypto_cipher_encrypt = (esp_crypto_cipher_encrypt_t)fast_crypto_cipher_encrypt, - .crypto_cipher_decrypt = (esp_crypto_cipher_decrypt_t)fast_crypto_cipher_decrypt, - .crypto_cipher_deinit = (esp_crypto_cipher_deinit_t)fast_crypto_cipher_deinit, - .crypto_mod_exp = (esp_crypto_mod_exp_t)crypto_mod_exp, - .sha256_vector = (esp_sha256_vector_t)fast_sha256_vector, - .tls_init = (esp_tls_init_t)tls_init, - .tls_deinit = (esp_tls_deinit_t)tls_deinit, - .eap_peer_blob_init = (esp_eap_peer_blob_init_t)eap_peer_blob_init, - .eap_peer_blob_deinit = (esp_eap_peer_blob_deinit_t)eap_peer_blob_deinit, - .eap_peer_config_init = (esp_eap_peer_config_init_t)eap_peer_config_init, - .eap_peer_config_deinit = (esp_eap_peer_config_deinit_t)eap_peer_config_deinit, - .eap_peer_register_methods = (esp_eap_peer_register_methods_t)eap_peer_register_methods, - .eap_peer_unregister_methods = (esp_eap_peer_unregister_methods_t)eap_peer_unregister_methods, - .eap_deinit_prev_method = (esp_eap_deinit_prev_method_t)eap_deinit_prev_method, - .eap_peer_get_eap_method = (esp_eap_peer_get_eap_method_t)eap_peer_get_eap_method, - .eap_sm_abort = (esp_eap_sm_abort_t)eap_sm_abort, - .eap_sm_build_nak = (esp_eap_sm_build_nak_t)eap_sm_build_nak, - .eap_sm_build_identity_resp = (esp_eap_sm_build_identity_resp_t)eap_sm_build_identity_resp, - .eap_msg_alloc = (esp_eap_msg_alloc_t)eap_msg_alloc -}; -#else - -/* - * The parameters is used to set the cyrpto callback function for station connect when in security mode, - * every callback function can register as fast_xxx or normal one, i.e, fast_aes_wrap or aes_wrap, the - * difference between them is the normal API is calculate by software, the fast one use the hardware - * crypto in it, can be faster than the normal one, so the callback function register in default is which - * we recommend, so as the API in WPS default and WPA2 default. - */ -const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs = { - .size = sizeof(wpa_crypto_funcs_t), - .version = ESP_WIFI_CRYPTO_VERSION, - .aes_wrap = (esp_aes_wrap_t)aes_wrap, - .aes_unwrap = (esp_aes_unwrap_t)aes_unwrap, - .hmac_sha256_vector = (esp_hmac_sha256_vector_t)hmac_sha256_vector, - .sha256_prf = (esp_sha256_prf_t)fast_sha256_prf, - .hmac_md5 = (esp_hmac_md5_t)hmac_md5, - .hamc_md5_vector = (esp_hmac_md5_vector_t)hmac_md5_vector, - .hmac_sha1 = (esp_hmac_sha1_t)hmac_sha1, - .hmac_sha1_vector = (esp_hmac_sha1_vector_t)hmac_sha1_vector, - .sha1_prf = (esp_sha1_prf_t)sha1_prf, - .sha1_vector = (esp_sha1_vector_t)sha1_vector, - .pbkdf2_sha1 = (esp_pbkdf2_sha1_t)pbkdf2_sha1, - .rc4_skip = (esp_rc4_skip_t)rc4_skip, - .md5_vector = (esp_md5_vector_t)md5_vector, - .aes_encrypt = (esp_aes_encrypt_t)aes_encrypt, - .aes_encrypt_init = (esp_aes_encrypt_init_t)aes_encrypt_init, - .aes_encrypt_deinit = (esp_aes_encrypt_deinit_t)aes_encrypt_deinit, - .aes_decrypt = (esp_aes_decrypt_t)aes_decrypt, - .aes_decrypt_init = (esp_aes_decrypt_init_t)aes_decrypt_init, - .aes_decrypt_deinit = (esp_aes_decrypt_deinit_t)aes_decrypt_deinit -}; - -const wps_crypto_funcs_t g_wifi_default_wps_crypto_funcs = { - .size = sizeof(wps_crypto_funcs_t), - .version = ESP_WIFI_CRYPTO_VERSION, - .aes_128_encrypt = (esp_aes_128_encrypt_t)aes_128_cbc_encrypt, - .aes_128_decrypt = (esp_aes_128_decrypt_t)aes_128_cbc_decrypt, - .crypto_mod_exp = (esp_crypto_mod_exp_t)crypto_mod_exp, - .hmac_sha256 = (esp_hmac_sha256_t)hmac_sha256, - .hmac_sha256_vector = (esp_hmac_sha256_vector_t)hmac_sha256_vector, - .sha256_vector = (esp_sha256_vector_t)sha256_vector, - .uuid_gen_mac_addr = (esp_uuid_gen_mac_addr_t)uuid_gen_mac_addr, - .dh5_free = (esp_dh5_free_t)dh5_free, - .wps_build_assoc_req_ie = (esp_wps_build_assoc_req_ie_t)wps_build_assoc_req_ie, - .wps_build_assoc_resp_ie = (esp_wps_build_assoc_resp_ie_t)wps_build_assoc_resp_ie, - .wps_build_probe_req_ie = (esp_wps_build_probe_req_ie_t)wps_build_probe_req_ie, - .wps_build_public_key = (esp_wps_build_public_key_t)wps_build_public_key, - .wps_enrollee_get_msg = (esp_wps_enrollee_get_msg_t)wps_enrollee_get_msg, - .wps_enrollee_process_msg = (esp_wps_enrollee_process_msg_t)wps_enrollee_process_msg, - .wps_generate_pin = (esp_wps_generate_pin_t)wps_generate_pin, - .wps_is_selected_pin_registrar = (esp_wps_is_selected_pin_registrar_t)wps_is_selected_pin_registrar, - .wps_is_selected_pbc_registrar = (esp_wps_is_selected_pbc_registrar_t)wps_is_selected_pbc_registrar, - .eap_msg_alloc = (esp_eap_msg_alloc_t)eap_msg_alloc -}; - -/* - * What should notice is that the cyrpto hash type function and crypto cipher type function can not register - * as different, i.e, if you use fast_crypto_hash_init, you should use fast_crypto_hash_update and - * fast_crypto_hash_finish for finish hash calculate, rather than call crypto_hash_update and - * crypto_hash_finish, so do crypto_cipher. - */ -const wpa2_crypto_funcs_t g_wifi_default_wpa2_crypto_funcs = { - .size = sizeof(wpa2_crypto_funcs_t), - .version = ESP_WIFI_CRYPTO_VERSION, - .crypto_hash_init = (esp_crypto_hash_init_t)crypto_hash_init, - .crypto_hash_update = (esp_crypto_hash_update_t)crypto_hash_update, - .crypto_hash_finish = (esp_crypto_hash_finish_t)crypto_hash_finish, - .crypto_cipher_init = (esp_crypto_cipher_init_t)crypto_cipher_init, - .crypto_cipher_encrypt = (esp_crypto_cipher_encrypt_t)crypto_cipher_encrypt, - .crypto_cipher_decrypt = (esp_crypto_cipher_decrypt_t)crypto_cipher_decrypt, - .crypto_cipher_deinit = (esp_crypto_cipher_deinit_t)crypto_cipher_deinit, - .crypto_mod_exp = (esp_crypto_mod_exp_t)crypto_mod_exp, - .sha256_vector = (esp_sha256_vector_t)sha256_vector, - .tls_init = (esp_tls_init_t)tls_init, - .tls_deinit = (esp_tls_deinit_t)tls_deinit, - .eap_peer_blob_init = (esp_eap_peer_blob_init_t)eap_peer_blob_init, - .eap_peer_blob_deinit = (esp_eap_peer_blob_deinit_t)eap_peer_blob_deinit, - .eap_peer_config_init = (esp_eap_peer_config_init_t)eap_peer_config_init, - .eap_peer_config_deinit = (esp_eap_peer_config_deinit_t)eap_peer_config_deinit, - .eap_peer_register_methods = (esp_eap_peer_register_methods_t)eap_peer_register_methods, - .eap_peer_unregister_methods = (esp_eap_peer_unregister_methods_t)eap_peer_unregister_methods, - .eap_deinit_prev_method = (esp_eap_deinit_prev_method_t)eap_deinit_prev_method, - .eap_peer_get_eap_method = (esp_eap_peer_get_eap_method_t)eap_peer_get_eap_method, - .eap_sm_abort = (esp_eap_sm_abort_t)eap_sm_abort, - .eap_sm_build_nak = (esp_eap_sm_build_nak_t)eap_sm_build_nak, - .eap_sm_build_identity_resp = (esp_eap_sm_build_identity_resp_t)eap_sm_build_identity_resp, - .eap_msg_alloc = (esp_eap_msg_alloc_t)eap_msg_alloc -}; -#endif \ No newline at end of file diff --git a/components/wpa_supplicant/src/fast_crypto/fast_sha256-internal.c b/components/wpa_supplicant/src/fast_crypto/fast_sha256-internal.c deleted file mode 100644 index 8b3c8a7e..00000000 --- a/components/wpa_supplicant/src/fast_crypto/fast_sha256-internal.c +++ /dev/null @@ -1,62 +0,0 @@ -// Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "sdkconfig.h" - -#include "utils/includes.h" -#include "utils/common.h" - -#if CONFIG_SSL_USING_MBEDTLS -#include "mbedtls/sha256.h" - -/** - * fast_sha256_vector - SHA256 hash for data vector - * @num_elem: Number of elements in the data vector - * @addr: Pointers to the data areas - * @len: Lengths of the data blocks - * @mac: Buffer for the hash - * Returns: 0 on success, -1 of failure - */ -int -fast_sha256_vector(size_t num_elem, const uint8_t *addr[], const size_t *len, - uint8_t *mac) -{ - int ret = 0; - mbedtls_sha256_context ctx; - - mbedtls_sha256_init(&ctx); - - if (mbedtls_sha256_starts_ret(&ctx, 0) != 0) { - ret = -1; - goto out; - } - - for(size_t index = 0; index < num_elem; index++) { - if (mbedtls_sha256_update_ret(&ctx, addr[index], len[index]) != 0) { - ret = -1; - goto out; - } - } - - if (mbedtls_sha256_finish_ret(&ctx, mac) != 0) { - ret = -1; - goto out; - } - -out: - mbedtls_sha256_free(&ctx); - - return ret; -} -#endif \ No newline at end of file diff --git a/components/wpa_supplicant/src/fast_crypto/fast_sha256.c b/components/wpa_supplicant/src/fast_crypto/fast_sha256.c deleted file mode 100644 index 63fd159a..00000000 --- a/components/wpa_supplicant/src/fast_crypto/fast_sha256.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * SHA-256 hash implementation and interface functions - * Copyright (c) 2003-2007, Jouni Malinen - * - * Hardware crypto support Copyright 2017 Espressif Systems (Shanghai) PTE LTD - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ -#include "sdkconfig.h" - -#include "utils/includes.h" - -#include "utils/common.h" -#include "crypto/sha256.h" -#include "crypto/crypto.h" - -int fast_sha256_vector(size_t num_elem, const uint8_t *addr[], const size_t *len, - uint8_t *mac); - -#if CONFIG_SSL_USING_MBEDTLS -/** - * fast_hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104) - * @key: Key for HMAC operations - * @key_len: Length of the key in bytes - * @num_elem: Number of elements in the data vector - * @addr: Pointers to the data areas - * @len: Lengths of the data blocks - * @mac: Buffer for the hash (32 bytes) - */ -void -fast_hmac_sha256_vector(const uint8_t *key, size_t key_len, size_t num_elem, - const uint8_t *addr[], const size_t *len, uint8_t *mac) -{ - uint8_t k_pad[64]; /* padding - key XORd with ipad/opad */ - uint8_t tk[32]; - const uint8_t *_addr[6]; - size_t _len[6], i; - - if (num_elem > 5) { - /* - * Fixed limit on the number of fragments to avoid having to - * allocate memory (which could fail). - */ - return; - } - - /* if key is longer than 64 bytes reset it to key = SHA256(key) */ - if (key_len > 64) { - fast_sha256_vector(1, &key, &key_len, tk); - key = tk; - key_len = 32; - } - - /* the HMAC_SHA256 transform looks like: - * - * SHA256(K XOR opad, SHA256(K XOR ipad, text)) - * - * where K is an n byte key - * ipad is the byte 0x36 repeated 64 times - * opad is the byte 0x5c repeated 64 times - * and text is the data being protected - */ - - /* start out by storing key in ipad */ - os_memset(k_pad, 0, sizeof(k_pad)); - os_memcpy(k_pad, key, key_len); - /* XOR key with ipad values */ - for (i = 0; i < 64; i++) { - k_pad[i] ^= 0x36; - } - - /* perform inner SHA256 */ - _addr[0] = k_pad; - _len[0] = 64; - for (i = 0; i < num_elem; i++) { - _addr[i + 1] = addr[i]; - _len[i + 1] = len[i]; - } - fast_sha256_vector(1 + num_elem, _addr, _len, mac); - - os_memset(k_pad, 0, sizeof(k_pad)); - os_memcpy(k_pad, key, key_len); - /* XOR key with opad values */ - for (i = 0; i < 64; i++) { - k_pad[i] ^= 0x5c; - } - - /* perform outer SHA256 */ - _addr[0] = k_pad; - _len[0] = 64; - _addr[1] = mac; - _len[1] = SHA256_MAC_LEN; - fast_sha256_vector(2, _addr, _len, mac); -} - - -/** - * fast_hmac_sha256 - HMAC-SHA256 over data buffer (RFC 2104) - * @key: Key for HMAC operations - * @key_len: Length of the key in bytes - * @data: Pointers to the data area - * @data_len: Length of the data area - * @mac: Buffer for the hash (20 bytes) - */ -void -fast_hmac_sha256(const uint8_t *key, size_t key_len, const uint8_t *data, - size_t data_len, uint8_t *mac) -{ - fast_hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac); -} - - -/** - * fast_sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2) - * @key: Key for PRF - * @key_len: Length of the key in bytes - * @label: A unique label for each purpose of the PRF - * @data: Extra data to bind into the key - * @data_len: Length of the data - * @buf: Buffer for the generated pseudo-random key - * @buf_len: Number of bytes of key to generate - * - * This function is used to derive new, cryptographically separate keys from a - * given key. - */ -void -fast_sha256_prf(const uint8_t *key, size_t key_len, const char *label, - const uint8_t *data, size_t data_len, uint8_t *buf, size_t buf_len) -{ - uint16_t counter = 1; - size_t pos, plen; - uint8_t hash[SHA256_MAC_LEN]; - const uint8_t *addr[4]; - size_t len[4]; - uint8_t counter_le[2], length_le[2]; - - addr[0] = counter_le; - len[0] = 2; - addr[1] = (uint8_t *) label; - len[1] = os_strlen(label); - addr[2] = data; - len[2] = data_len; - addr[3] = length_le; - len[3] = sizeof(length_le); - - WPA_PUT_LE16(length_le, buf_len * 8); - pos = 0; - while (pos < buf_len) { - plen = buf_len - pos; - WPA_PUT_LE16(counter_le, counter); - if (plen >= SHA256_MAC_LEN) { - fast_hmac_sha256_vector(key, key_len, 4, addr, len, - &buf[pos]); - pos += SHA256_MAC_LEN; - } else { - fast_hmac_sha256_vector(key, key_len, 4, addr, len, hash); - os_memcpy(&buf[pos], hash, plen); - break; - } - counter++; - } -} -#endif \ No newline at end of file diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index c0d541a9..3455326b 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -41,8 +41,8 @@ * been completed successfully since WPA-PSK does not use EAP state machine. */ -#define WPA_4_4_HANDSHAKE_BIT (1<<6) //(1<<13) -#define WPA_GROUP_HANDSHAKE_BIT (1<<7) //(1<<14) +#define WPA_4_4_HANDSHAKE_BIT (1<<13) +#define WPA_GROUP_HANDSHAKE_BIT (1<<14) struct wpa_sm gWpaSm; /* fix buf for tx for now */ #define WPA_TX_MSG_BUFF_MAXLEN 200 @@ -1944,7 +1944,7 @@ int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len) #ifdef DEBUG_PRINT wpa_printf(MSG_INFO, "EAPOL1 received for %d times, sending deauth", sm->eapol1_count); #endif - // esp_wifi_internal_issue_disconnect(WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT); + esp_wifi_internal_issue_disconnect(WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT); goto out; } wpa_supplicant_process_1_of_4(sm, src_addr, key, @@ -2044,9 +2044,9 @@ void wpa_sm_set_pmk_from_pmksa(struct wpa_sm *sm) #ifdef ESP_SUPPLICANT -void wpa_register(char* payload, WPA_SEND_FUNC snd_func, - WPA_SET_ASSOC_IE set_assoc_ie_func, WPA_INSTALL_KEY ppinstallkey, WPA_GET_KEY ppgetkey, WPA_DEAUTH_FUNC wpa_deauth, - WPA_NEG_COMPLETE wpa_neg_complete) +bool wpa_sm_init(char * payload, WPA_SEND_FUNC snd_func, + WPA_SET_ASSOC_IE set_assoc_ie_func, WPA_INSTALL_KEY ppinstallkey, WPA_GET_KEY ppgetkey, WPA_DEAUTH_FUNC wpa_deauth, + WPA_NEG_COMPLETE wpa_neg_complete) { struct wpa_sm *sm = &gWpaSm; @@ -2140,6 +2140,9 @@ int wpa_set_bss(char *macddr, char * bssid, u8 pairwise_cipher, u8 group_cipher, esp_wifi_get_config(ESP_IF_WIFI_STA, &wifi_cfg); sm->pmf_cfg = wifi_cfg.sta.pmf_cfg; sm->mgmt_group_cipher = cipher_type_map_public_to_supp(esp_wifi_sta_get_mgmt_group_cipher()); + } else { + memset(&sm->pmf_cfg, 0, sizeof(sm->pmf_cfg)); + sm->mgmt_group_cipher = WPA_CIPHER_NONE; } #endif set_assoc_ie(assoc_ie_buf); /* use static buffer */ @@ -2172,11 +2175,11 @@ wpa_set_passphrase(char * passphrase, u8 *ssid, size_t ssid_len) /* This is really SLOW, so just re cacl while reset param */ if (esp_wifi_sta_get_reset_param_internal() != 0) { // check it's psk - if (os_strlen((char *)esp_wifi_sta_get_prof_password_internal()) == 64) { - hexstr2bin((char *)esp_wifi_sta_get_prof_password_internal(), esp_wifi_sta_get_prof_pmk_internal(), PMK_LEN); + if (strlen((char *)esp_wifi_sta_get_prof_password_internal()) == 64) { + hexstr2bin((char *)esp_wifi_sta_get_prof_password_internal(), esp_wifi_sta_get_ap_info_prof_pmk_internal(), PMK_LEN); } else { pbkdf2_sha1((char *)esp_wifi_sta_get_prof_password_internal(), (char *)sta_ssid->ssid, (size_t)sta_ssid->len, - 4096, esp_wifi_sta_get_prof_pmk_internal(), PMK_LEN); + 4096, esp_wifi_sta_get_ap_info_prof_pmk_internal(), PMK_LEN); } esp_wifi_sta_update_ap_info_internal(); esp_wifi_sta_set_reset_param_internal(0); @@ -2372,6 +2375,15 @@ bool wpa_sta_is_cur_pmksa_set(void) { return (pmksa_cache_get_current(sm) != NULL); } +bool wpa_sta_cur_pmksa_matches_akm(void) { + struct wpa_sm *sm = &gWpaSm; + struct rsn_pmksa_cache_entry *pmksa; + + pmksa = pmksa_cache_get_current(sm); + return (pmksa != NULL && + sm->key_mgmt == pmksa->akmp); +} + void wpa_sta_clear_curr_pmksa(void) { struct wpa_sm *sm = &gWpaSm; diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.h b/components/wpa_supplicant/src/rsn_supp/wpa.h index ab2ac033..e0c63fe4 100755 --- a/components/wpa_supplicant/src/rsn_supp/wpa.h +++ b/components/wpa_supplicant/src/rsn_supp/wpa.h @@ -39,6 +39,7 @@ struct wpa_sm; int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len); bool wpa_sta_is_cur_pmksa_set(void); bool wpa_sta_in_4way_handshake(void); +bool wpa_sta_cur_pmksa_matches_akm(void); #define WPA_ASSERT assert @@ -127,6 +128,8 @@ int wpa_hook_init(void); bool wpa_hook_deinit(void); +char * dup_binstr(const void *src, size_t len); + int wpa_michael_mic_failure(u16 isunicast); wifi_cipher_type_t cipher_type_map_supp_to_public(uint32_t wpa_cipher); diff --git a/components/wpa_supplicant/src/rsn_supp/wpa_i.h b/components/wpa_supplicant/src/rsn_supp/wpa_i.h index e64d5db8..831810a5 100755 --- a/components/wpa_supplicant/src/rsn_supp/wpa_i.h +++ b/components/wpa_supplicant/src/rsn_supp/wpa_i.h @@ -152,7 +152,7 @@ typedef void (*WPA_DEAUTH_FUNC)(u8 reason_code); typedef void (*WPA_NEG_COMPLETE)(void); -void wpa_register(char * payload, WPA_SEND_FUNC snd_func, \ +bool wpa_sm_init(char * payload, WPA_SEND_FUNC snd_func, \ WPA_SET_ASSOC_IE set_assoc_ie_func, \ WPA_INSTALL_KEY ppinstallkey, \ WPA_GET_KEY ppgetkey, \ diff --git a/components/wpa_supplicant/src/wps/wps.h b/components/wpa_supplicant/src/wps/wps.h index ab256489..5df3252d 100644 --- a/components/wpa_supplicant/src/wps/wps.h +++ b/components/wpa_supplicant/src/wps/wps.h @@ -1009,10 +1009,19 @@ enum wps_cb_status { typedef void (*wps_st_cb_t)(int status); -#if 1//def USE_WPS_TASK -#define SIG_WPS_START 0 -#define SIG_WPS_RX 1 -#define SIG_WPS_NUM 2 +#ifdef USE_WPS_TASK +enum wps_sig_type { + SIG_WPS_ENABLE = 1, //1 + SIG_WPS_DISABLE, //2 + SIG_WPS_START, //3 + SIG_WPS_RX, //4 + SIG_WPS_TIMER_TIMEOUT, //5 + SIG_WPS_TIMER_MSG_TIMEOUT, //6 + SIG_WPS_TIMER_SUCCESS_CB, //7 + SIG_WPS_TIMER_SCAN, //8 + SIG_WPS_TIMER_EAPOL_START, //9 + SIG_WPS_NUM, //10 +}; #endif #define WPS_EAP_EXT_VENDOR_TYPE "WFA-SimpleConfig-Enrollee-1-0" @@ -1025,13 +1034,14 @@ struct wps_sm { u8 identity_len; u8 ownaddr[ETH_ALEN]; u8 bssid[ETH_ALEN]; - u8 ssid[32]; - u8 ssid_len; + u8 ssid[MAX_WPS_AP_CRED][MAX_SSID_LEN]; + u8 ssid_len[MAX_WPS_AP_CRED]; + char key[MAX_WPS_AP_CRED][MAX_PASSPHRASE_LEN]; + u8 key_len[MAX_WPS_AP_CRED]; + u8 ap_cred_cnt; struct wps_device_data *dev; u8 uuid[16]; u8 eapol_version; - char key[64]; - u8 key_len; ETSTimer wps_timeout_timer; ETSTimer wps_msg_timeout_timer; ETSTimer wps_scan_timer; @@ -1055,8 +1065,8 @@ struct wps_sm { #define WIFI_CAPINFO_PRIVACY 0x0010 struct wps_sm *wps_sm_get(void); -int wps_ssid_save(u8 *ssid, u8 ssid_len); -int wps_key_save(char *key, u8 key_len); +int wps_ssid_save(u8 *ssid, u8 ssid_len, u8 idx); +int wps_key_save(char *key, u8 key_len, u8 idx); int wps_station_wps_register_cb(wps_st_cb_t cb); int wps_station_wps_unregister_cb(void); int wps_start_pending(void); diff --git a/components/wpa_supplicant/src/wps/wps_enrollee.c b/components/wpa_supplicant/src/wps/wps_enrollee.c index 1e48fe78..ed733c6c 100644 --- a/components/wpa_supplicant/src/wps/wps_enrollee.c +++ b/components/wpa_supplicant/src/wps/wps_enrollee.c @@ -654,7 +654,7 @@ static int wps_process_r_snonce2(struct wps_data *wps, const u8 *r_snonce2) static int wps_process_cred_e(struct wps_data *wps, const u8 *cred, - size_t cred_len, int wps2) + size_t cred_len, int cred_idx, int wps2) { struct wps_parse_attr *attr; struct wpabuf msg; @@ -714,9 +714,8 @@ static int wps_process_cred_e(struct wps_data *wps, const u8 *cred, goto _out; } #endif /* CONFIG_WPS2 */ - - wps_ssid_save(wps->cred.ssid, wps->cred.ssid_len); - wps_key_save((char *)wps->cred.key, wps->cred.key_len); + wps_ssid_save(wps->cred.ssid, wps->cred.ssid_len, cred_idx); + wps_key_save((char *)wps->cred.key, wps->cred.key_len, cred_idx); if (wps->wps->cred_cb) { wps->cred.cred_attr = cred - 4; @@ -751,7 +750,7 @@ static int wps_process_creds(struct wps_data *wps, const u8 *cred[], for (i = 0; i < num_cred; i++) { int res; - res = wps_process_cred_e(wps, cred[i], cred_len[i], wps2); + res = wps_process_cred_e(wps, cred[i], cred_len[i], i, wps2); if (res == 0) ok++; else if (res == -2) { diff --git a/components/wpa_supplicant/src/wps/wps_i.h b/components/wpa_supplicant/src/wps/wps_i.h index 9c4b1585..5cdd51ec 100644 --- a/components/wpa_supplicant/src/wps/wps_i.h +++ b/components/wpa_supplicant/src/wps/wps_i.h @@ -125,40 +125,6 @@ struct wps_data { #endif }; -#if 0 -typedef enum wps_type { - WPS_TYPE_DISABLE = 0, - WPS_TYPE_E_PBC, - WPS_TYPE_E_PIN, - WPS_TYPE_E_DISPLAY, - WPS_TYPE_E_MAX, - WPS_TYPE_R_PBC, - WPS_TYPE_R_PIN, - WPS_TYPE_R_DISPLAY, - WPS_TYPE_R_MAX, - WPS_TYPE_ALL_MAX, -} WPS_TYPE_t; - -#define WPS_MAX_MANUFACTURER_LEN 65 -#define WPS_MAX_MODEL_NUMBER_LEN 33 -#define WPS_MAX_MODEL_NAME_LEN 33 -#define WPS_MAX_DEV_NAME_LEN 33 -typedef struct { - char manufacturer[WPS_MAX_MANUFACTURER_LEN]; - char model_number[WPS_MAX_MODEL_NUMBER_LEN]; - char model_name[WPS_MAX_MODEL_NAME_LEN]; - char device_name[WPS_MAX_DEV_NAME_LEN]; -} esp_factory_information_t; - -typedef struct { - WPS_TYPE_t wps_type; - const wps_crypto_funcs_t *crypto_funcs; - esp_factory_information_t factory_info; -}esp_wps_config_t; - -wps_crypto_funcs_t wps_crypto_funcs; -#endif - /* wps_common.c */ void wps_kdf(const u8 *key, const u8 *label_prefix, size_t label_prefix_len, const char *label, u8 *res, size_t res_len); diff --git a/examples/wifi/wpa2_enterprise/main/wpa2_enterprise_main.c b/examples/wifi/wpa2_enterprise/main/wpa2_enterprise_main.c index ac6ec782..3c1d7505 100644 --- a/examples/wifi/wpa2_enterprise/main/wpa2_enterprise_main.c +++ b/examples/wifi/wpa2_enterprise/main/wpa2_enterprise_main.c @@ -101,7 +101,6 @@ static void initialise_wifi(void) unsigned int ca_pem_bytes = ca_pem_end - ca_pem_start; unsigned int client_crt_bytes = client_crt_end - client_crt_start; unsigned int client_key_bytes = client_key_end - client_key_start; - esp_wpa2_config_t config = WPA2_CONFIG_INIT_DEFAULT(); tcpip_adapter_init(); wifi_event_group = xEventGroupCreate(); @@ -129,7 +128,7 @@ static void initialise_wifi(void) ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_set_password((uint8_t*)EXAMPLE_EAP_PASSWORD, strlen(EXAMPLE_EAP_PASSWORD))); } - ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_enable(&config)); + ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_enable()); ESP_ERROR_CHECK(esp_wifi_start()); }