esp_wifi: Update wifi lib

1. Use flag ESP32_WIFI_ENABLE_WPA3_SAE to control WPA3 code, disabling
   it code footprint reduces by 7.7kB in libwpa_supplicant.a
2. Fix handling of multiple AP credentials in WPS, apps need update
   to handle the new event for the fix to work
This commit is contained in:
Nachiket Kukade 2020-10-28 18:21:50 +05:30 committed by zhangyanjiao
parent b2dec946b6
commit 2db6b1578e
11 changed files with 142 additions and 49 deletions

View File

@ -80,6 +80,9 @@ typedef wifi_event_sta_authmode_change_t system_event_sta_authmode_change_t;
/** Argument structure of SYSTEM_EVENT_STA_WPS_ER_PIN event */
typedef wifi_event_sta_wps_er_pin_t system_event_sta_wps_er_pin_t;
/** Argument structure of SYSTEM_EVENT_STA_WPS_ER_PIN event */
typedef wifi_event_sta_wps_er_success_t system_event_sta_wps_er_success_t;
/** Argument structure of event */
typedef wifi_event_ap_staconnected_t system_event_ap_staconnected_t;
@ -107,6 +110,7 @@ typedef union {
system_event_sta_got_ip_t got_ip; /*!< ESP32 station got IP, first time got IP or when IP is changed */
system_event_sta_wps_er_pin_t sta_er_pin; /*!< ESP32 station WPS enrollee mode PIN code received */
system_event_sta_wps_fail_reason_t sta_er_fail_reason; /*!< ESP32 station WPS enrollee mode failed reason code received */
system_event_sta_wps_er_success_t sta_er_success; /*!< ESP32 station WPS enrollee success */
system_event_ap_staconnected_t sta_connected; /*!< a station connected to ESP32 soft-AP */
system_event_ap_stadisconnected_t sta_disconnected; /*!< a station disconnected to ESP32 soft-AP */
system_event_ap_probe_req_rx_t ap_probereqrecved; /*!< ESP32 soft-AP receive probe request packet */

View File

@ -569,6 +569,19 @@ typedef enum {
WPS_FAIL_REASON_MAX
} wifi_event_sta_wps_fail_reason_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_SUCCESS event */
typedef struct {
uint8_t ap_cred_cnt; /**< Number of AP credentials received */
struct {
uint8_t ssid[MAX_SSID_LEN]; /**< SSID of AP */
uint8_t passphrase[MAX_PASSPHRASE_LEN]; /**< Passphrase for the AP */
} ap_cred[MAX_WPS_AP_CRED]; /**< All AP credentials received from WPS handshake */
} wifi_event_sta_wps_er_success_t;
/** Argument structure for WIFI_EVENT_AP_STACONNECTED event */
typedef struct {
uint8_t mac[6]; /**< MAC address of the station connected to ESP32 soft-AP */

View File

@ -123,7 +123,10 @@ target_compile_definitions(${COMPONENT_LIB} PRIVATE
CONFIG_ECC
CONFIG_SHA256
CONFIG_IEEE80211W
CONFIG_WPA3_SAE
)
if(CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE)
target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_WPA3_SAE)
endif()
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY LINK_INTERFACE_MULTIPLICITY 3)

View File

@ -26,4 +26,8 @@ else
COMPONENT_OBJEXCLUDE := src/crypto/tls_mbedtls.o
endif
CFLAGS += -DCONFIG_WPA3_SAE -DCONFIG_IEEE80211W -DESP_SUPPLICANT -DIEEE8021X_EAPOL -DEAP_PEER_METHOD -DEAP_TLS -DEAP_TTLS -DEAP_PEAP -DEAP_MSCHAPv2 -DUSE_WPA2_TASK -DCONFIG_WPS2 -DCONFIG_WPS_PIN -DUSE_WPS_TASK -DESPRESSIF_USE -DESP32_WORKAROUND -DCONFIG_ECC -D__ets__ -Wno-strict-aliasing
CFLAGS += -DCONFIG_IEEE80211W -DESP_SUPPLICANT -DIEEE8021X_EAPOL -DEAP_PEER_METHOD -DEAP_TLS -DEAP_TTLS -DEAP_PEAP -DEAP_MSCHAPv2 -DUSE_WPA2_TASK -DCONFIG_WPS2 -DCONFIG_WPS_PIN -DUSE_WPS_TASK -DESPRESSIF_USE -DESP32_WORKAROUND -DCONFIG_ECC -D__ets__ -Wno-strict-aliasing
ifdef CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE
CFLAGS += -DCONFIG_WPA3_SAE
endif

View File

@ -58,11 +58,11 @@ static int rsn_key_mgmt_to_bitfield(const u8 *s)
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_FT_PSK)
return WPA_KEY_MGMT_FT_PSK;
#endif /* CONFIG_IEEE80211R */
#ifdef CONFIG_IEEE80211W
#ifdef CONFIG_WPA3_SAE
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_SAE)
return WPA_KEY_MGMT_SAE;
#endif /* CONFIG_WPA3_SAE */
#ifdef CONFIG_IEEE80211W
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SHA256)
return WPA_KEY_MGMT_IEEE8021X_SHA256;
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_PSK_SHA256)
@ -396,10 +396,10 @@ int wpa_eapol_key_mic(const u8 *key, int ver, const u8 *buf, size_t len,
#ifdef CONFIG_IEEE80211W
#ifdef CONFIG_WPA3_SAE
case WPA_KEY_INFO_TYPE_AKM_DEFINED:
#endif
#endif /* CONFIG_WPA3_SAE */
case WPA_KEY_INFO_TYPE_AES_128_CMAC:
return omac1_aes_128(key, buf, len, mic);
#endif
#endif /* CONFIG_IEEE80211W */
default:
return -1;
}

View File

@ -31,5 +31,9 @@ static inline void esp_wifi_register_wpa3_cb(struct wpa_funcs *wpa_cb)
wpa_cb->wpa3_parse_sae_msg = NULL;
}
static inline void esp_wpa3_free_sae_data(void)
{
}
#endif /* CONFIG_WPA3_SAE */
#endif /* ESP_WPA3_H */

View File

@ -594,19 +594,16 @@ wps_parse_scan_result(struct wps_scan_ie *scan)
}
esp_wifi_enable_sta_privacy_internal();
os_bzero(sm->ssid, sizeof(sm->ssid));
strncpy((char *)sm->ssid, (char *)&scan->ssid[2], (int)scan->ssid[1]);
sm->ssid_len = scan->ssid[1];
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]", sm->ssid);
wpa_printf(MSG_DEBUG, "wps discover [%s]", (char *)sm->config.ssid);
sm->scan_cnt = 0;
memcpy(sm->config.ssid, sm->ssid, sm->ssid_len);
sm->channel = scan->chan;
return true;
@ -944,9 +941,10 @@ int wps_stop_process(system_event_sta_wps_fail_reason_t reason_code)
sm->discover_ssid_cnt = 0;
sm->wps->state = SEND_M1;
os_bzero(sm->bssid, ETH_ALEN);
os_bzero(sm->ssid, 32);
sm->ssid_len = 0;
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);
@ -988,15 +986,17 @@ int wps_finish(void)
ets_timer_disarm(&sm->wps_timeout_timer);
ets_timer_disarm(&sm->wps_msg_timeout_timer);
memset(config, 0x00, sizeof(wifi_sta_config_t));
memcpy(config->sta.ssid, sm->ssid, sm->ssid_len);
memcpy(config->sta.password, sm->key, sm->key_len);
memcpy(config->sta.bssid, sm->bssid, ETH_ALEN);
config->sta.bssid_set = 0;
esp_wifi_set_config(0, config);
os_free(config);
config = NULL;
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);
@ -1505,7 +1505,25 @@ void wifi_station_wps_success_internal(void)
{
system_event_t evt;
evt.event_id = SYSTEM_EVENT_STA_WPS_ER_SUCCESS;
esp_wifi_send_event_internal(&evt);
struct wps_sm *sm = gWpsSm;
int i;
/*
* For only one AP credential don't sned event data, wps_finish() has already set
* the config. This is for backward compatibility.
*/
if (sm->ap_cred_cnt > 1) {
evt.event_info.sta_er_success.ap_cred_cnt = sm->ap_cred_cnt;
for (i = 0; i < MAX_WPS_AP_CRED; i++) {
os_memcpy(evt.event_info.sta_er_success.ap_cred[i].ssid,
sm->ssid[i], sm->ssid_len[i]);
os_memcpy(evt.event_info.sta_er_success.ap_cred[i].passphrase,
sm->key[i], sm->key_len[i]);
}
esp_wifi_send_event_internal(&evt);
} else {
esp_wifi_send_event_internal(&evt);
}
}
void wifi_station_wps_success(void)
@ -1716,44 +1734,45 @@ wps_sm_get(void)
}
int
wps_ssid_save(u8 *ssid, u8 ssid_len)
wps_ssid_save(u8 *ssid, u8 ssid_len, u8 idx)
{
u8 *tmpssid;
if (!ssid || !gWpsSm) {
if (!ssid || !gWpsSm || idx > 2) {
return ESP_FAIL;
}
memset(gWpsSm->ssid, 0x00, sizeof(gWpsSm->ssid));
memcpy(gWpsSm->ssid, ssid, ssid_len);
gWpsSm->ssid_len = ssid_len;
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: ssid[%s]", tmpssid);
wpa_printf(MSG_DEBUG, "WPS: key[%s]", tmpssid);
os_free(tmpssid);
}
return ESP_OK;
}
int
wps_key_save(char *key, u8 key_len)
wps_key_save(char *key, u8 key_len, u8 idx)
{
u8 *tmpkey;
if (!key || !gWpsSm) {
if (!key || !gWpsSm || idx > 2) {
return ESP_FAIL;
}
memset(gWpsSm->key, 0x00, sizeof(gWpsSm->key));
memcpy(gWpsSm->key, key, key_len);
gWpsSm->key_len = key_len;
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]", tmpkey);
wpa_printf(MSG_DEBUG, "WPS: key[%s], idx - %d", tmpkey, idx);
os_free(tmpkey);
}
return ESP_OK;

View File

@ -203,11 +203,11 @@ static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA256);
} else if (key_mgmt == WPA_KEY_MGMT_PSK_SHA256) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_SHA256);
#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_WPA3_SAE
} else if (key_mgmt == WPA_KEY_MGMT_SAE) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE);
#endif /* CONFIG_WPA3_SAE */
#endif /* CONFIG_IEEE80211W */
} else {
wpa_printf(MSG_DEBUG, "Invalid key management type (%d).",
key_mgmt);

View File

@ -1027,13 +1027,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;
@ -1057,8 +1058,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);

View File

@ -651,7 +651,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;
@ -711,9 +711,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;
@ -748,7 +747,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) {

View File

@ -27,6 +27,7 @@
#include "esp_wps.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include <string.h>
/*set wps mode via project configuration */
@ -38,6 +39,7 @@
#define WPS_MODE WPS_TYPE_DISABLE
#endif /*CONFIG_EXAMPLE_WPS_TYPE_PBC*/
#define MAX_RETRY_ATTEMPTS 2
#ifndef PIN2STR
#define PIN2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5], (a)[6], (a)[7]
@ -46,23 +48,67 @@
static const char *TAG = "example_wps";
static esp_wps_config_t config = WPS_CONFIG_INIT_DEFAULT(WPS_MODE);
static wifi_config_t wps_ap_creds[MAX_WPS_AP_CRED];
static int s_ap_creds_num = 0;
static int s_retry_num = 0;
static void wifi_event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
static int ap_idx = 1;
switch (event_id) {
case WIFI_EVENT_STA_START:
ESP_LOGI(TAG, "WIFI_EVENT_STA_START");
break;
case WIFI_EVENT_STA_DISCONNECTED:
ESP_LOGI(TAG, "WIFI_EVENT_STA_DISCONNECTED");
ESP_ERROR_CHECK(esp_wifi_connect());
if (s_retry_num < MAX_RETRY_ATTEMPTS) {
ESP_ERROR_CHECK(esp_wifi_connect());
s_retry_num++;
} else if (ap_idx < s_ap_creds_num) {
/* Try the next AP credential if first one fails */
if (ap_idx < s_ap_creds_num) {
ESP_LOGI(TAG, "Connecting to SSID: %s, Passphrase: %s",
wps_ap_creds[ap_idx].sta.ssid, wps_ap_creds[ap_idx].sta.password);
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wps_ap_creds[ap_idx++]) );
ESP_ERROR_CHECK(esp_wifi_connect());
}
s_retry_num = 0;
} else {
ESP_LOGI(TAG, "Failed to connect!");
}
break;
case WIFI_EVENT_STA_WPS_ER_SUCCESS:
ESP_LOGI(TAG, "WIFI_EVENT_STA_WPS_ER_SUCCESS");
/* esp_wifi_wps_start() only gets ssid & password, so call esp_wifi_connect() here. */
ESP_ERROR_CHECK(esp_wifi_wps_disable());
ESP_ERROR_CHECK(esp_wifi_connect());
{
wifi_event_sta_wps_er_success_t *evt =
(wifi_event_sta_wps_er_success_t *)event_data;
int i;
if (evt) {
s_ap_creds_num = evt->ap_cred_cnt;
for (i = 0; i < s_ap_creds_num; i++) {
memcpy(wps_ap_creds[i].sta.ssid, evt->ap_cred[i].ssid,
sizeof(evt->ap_cred[i].ssid));
memcpy(wps_ap_creds[i].sta.password, evt->ap_cred[i].passphrase,
sizeof(evt->ap_cred[i].passphrase));
}
/* If multiple AP credentials are received from WPS, connect with first one */
ESP_LOGI(TAG, "Connecting to SSID: %s, Passphrase: %s",
wps_ap_creds[0].sta.ssid, wps_ap_creds[0].sta.password);
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wps_ap_creds[0]) );
}
/*
* If only one AP credential is received from WPS, there will be no event data and
* esp_wifi_set_config() is already called by WPS modules for backward compatibility
* with legacy apps. So directly attempt connection here.
*/
ESP_ERROR_CHECK(esp_wifi_wps_disable());
ESP_ERROR_CHECK(esp_wifi_connect());
}
break;
case WIFI_EVENT_STA_WPS_ER_FAILED:
ESP_LOGI(TAG, "WIFI_EVENT_STA_WPS_ER_FAILED");