From 0ca6caa060ad698d14988442b4f0302903315b75 Mon Sep 17 00:00:00 2001 From: SubmarinePhantom Date: Wed, 6 Mar 2024 14:58:20 +0800 Subject: [PATCH] support WAPI Signed-off-by: SubmarinePhantom Change-Id: Ib4b6ada767bdae8d9f09b71786ff997b87839b1b --- wpa_supplicant-2.9_standard/BUILD.gn | 4 +- wpa_supplicant-2.9_standard/src/common/defs.h | 4 + .../src/common/ieee802_11_defs.h | 1 + .../src/common/wpa_common.c | 35 +++ .../src/common/wpa_common.h | 1 + .../src/drivers/driver.h | 8 + .../src/drivers/driver_nl80211.c | 28 ++- .../src/drivers/driver_nl80211_capa.c | 3 + .../src/l2_packet/l2_packet.h | 6 + .../src/l2_packet/l2_packet_linux.c | 94 ++++++++ .../src/rsn_supp/wpa_ie.c | 4 + wpa_supplicant-2.9_standard/wpa.gni | 2 + .../wpa_supplicant/ap.c | 3 + .../wpa_supplicant/bss.c | 9 + .../wpa_supplicant/bss.h | 3 + .../wpa_supplicant/config.c | 128 ++++++++++- .../wpa_supplicant/config_file.c | 52 ++++- .../wpa_supplicant/config_ssid.h | 24 ++ .../wpa_supplicant/ctrl_iface.c | 178 ++++++++++++++- .../wpa_supplicant/driver_i.h | 25 +++ .../wpa_supplicant/events.c | 199 +++++++++++++++- .../wpa_supplicant/wpa_supplicant.c | 212 ++++++++++++++++++ .../wpa_supplicant/wpa_supplicant_i.h | 13 ++ .../wpa_vendor_ext.gni | 7 + 24 files changed, 1034 insertions(+), 9 deletions(-) diff --git a/wpa_supplicant-2.9_standard/BUILD.gn b/wpa_supplicant-2.9_standard/BUILD.gn index 8dd81b2..1a7f31c 100644 --- a/wpa_supplicant-2.9_standard/BUILD.gn +++ b/wpa_supplicant-2.9_standard/BUILD.gn @@ -462,7 +462,7 @@ wpa_base_include_dirs = [ ] if (wpa_supplicant_vendor_ext) { - wpa_base_include_dirs += [ wpa_vendor_ext_inc_path ] + wpa_base_include_dirs += wpa_vendor_ext_inc_path } ohos_shared_library("wpa_sys") { @@ -1184,7 +1184,7 @@ ohos_executable("wpa_cli") { } if (wpa_supplicant_vendor_ext) { - include_dirs += [ wpa_vendor_ext_inc_path ] + include_dirs += wpa_vendor_ext_inc_path sources += wpa_vendor_ext_src_cli cflags += ext_cflags } diff --git a/wpa_supplicant-2.9_standard/src/common/defs.h b/wpa_supplicant-2.9_standard/src/common/defs.h index cc27383..e2bf53f 100644 --- a/wpa_supplicant-2.9_standard/src/common/defs.h +++ b/wpa_supplicant-2.9_standard/src/common/defs.h @@ -72,6 +72,10 @@ static inline int wpa_key_mgmt_wpa_ieee8021x(int akm) WPA_KEY_MGMT_OSEN | WPA_KEY_MGMT_IEEE8021X_SHA256 | WPA_KEY_MGMT_IEEE8021X_SUITE_B | +#ifdef CONFIG_WAPI + WPA_KEY_MGMT_WAPI_PSK | + WPA_KEY_MGMT_WAPI_CERT | +#endif WPA_KEY_MGMT_IEEE8021X_SUITE_B_192 | WPA_KEY_MGMT_FILS_SHA256 | WPA_KEY_MGMT_FILS_SHA384 | diff --git a/wpa_supplicant-2.9_standard/src/common/ieee802_11_defs.h b/wpa_supplicant-2.9_standard/src/common/ieee802_11_defs.h index f0ea99c..ba3d0ce 100644 --- a/wpa_supplicant-2.9_standard/src/common/ieee802_11_defs.h +++ b/wpa_supplicant-2.9_standard/src/common/ieee802_11_defs.h @@ -324,6 +324,7 @@ #define WLAN_EID_MEASUREMENT_PILOT_TRANSMISSION 66 #define WLAN_EID_BSS_AVAILABLE_ADM_CAPA 67 #define WLAN_EID_BSS_AC_ACCESS_DELAY 68 /* note: also used by WAPI */ +#define WLAN_EID_WAPI 68 #define WLAN_EID_TIME_ADVERTISEMENT 69 #define WLAN_EID_RRM_ENABLED_CAPABILITIES 70 #define WLAN_EID_MULTIPLE_BSSID 71 diff --git a/wpa_supplicant-2.9_standard/src/common/wpa_common.c b/wpa_supplicant-2.9_standard/src/common/wpa_common.c index d1cb9d2..ba3b161 100644 --- a/wpa_supplicant-2.9_standard/src/common/wpa_common.c +++ b/wpa_supplicant-2.9_standard/src/common/wpa_common.c @@ -19,6 +19,9 @@ #include "ieee802_11_defs.h" #include "defs.h" #include "wpa_common.h" +#ifdef CONFIG_WAPI +#include "securec.h" +#endif static unsigned int wpa_kck_len(int akmp, size_t pmk_len) @@ -2323,6 +2326,10 @@ const char * wpa_cipher_txt(int cipher) return "BIP-GMAC-256"; case WPA_CIPHER_BIP_CMAC_256: return "BIP-CMAC-256"; +#ifdef CONFIG_WAPI + case WPA_CIPHER_SMS4: + return "SMS4"; +#endif case WPA_CIPHER_GTK_NOT_USED: return "GTK_NOT_USED"; default: @@ -2648,12 +2655,14 @@ int wpa_cipher_valid_pairwise(int cipher) return cipher == WPA_CIPHER_CCMP_256 || cipher == WPA_CIPHER_GCMP_256 || cipher == WPA_CIPHER_CCMP || + cipher == WPA_CIPHER_SMS4 || cipher == WPA_CIPHER_GCMP; #else /* CONFIG_NO_TKIP */ return cipher == WPA_CIPHER_CCMP_256 || cipher == WPA_CIPHER_GCMP_256 || cipher == WPA_CIPHER_CCMP || cipher == WPA_CIPHER_GCMP || + cipher == WPA_CIPHER_SMS4 || cipher == WPA_CIPHER_TKIP; #endif /* CONFIG_NO_TKIP */ } @@ -2686,6 +2695,10 @@ u32 wpa_cipher_to_suite(int proto, int cipher) return RSN_CIPHER_SUITE_BIP_GMAC_256; if (cipher & WPA_CIPHER_BIP_CMAC_256) return RSN_CIPHER_SUITE_BIP_CMAC_256; +#ifdef CONFIG_WAPI + if (cipher & WPA_CIPHER_SMS4) + return RSN_CIPHER_SUITE_SMS4; +#endif return 0; } @@ -2756,6 +2769,10 @@ int wpa_pick_pairwise_cipher(int ciphers, int none_allowed) return WPA_CIPHER_GCMP; if (ciphers & WPA_CIPHER_TKIP) return WPA_CIPHER_TKIP; +#ifdef CONFIG_WAPI + if (ciphers & WPA_CIPHER_SMS4) + return WPA_CIPHER_SMS4; +#endif if (none_allowed && (ciphers & WPA_CIPHER_NONE)) return WPA_CIPHER_NONE; return -1; @@ -2776,6 +2793,10 @@ int wpa_pick_group_cipher(int ciphers) return WPA_CIPHER_GTK_NOT_USED; if (ciphers & WPA_CIPHER_TKIP) return WPA_CIPHER_TKIP; +#ifdef CONFIG_WAPI + if (ciphers & WPA_CIPHER_SMS4) + return WPA_CIPHER_SMS4; +#endif return -1; } @@ -2820,6 +2841,10 @@ int wpa_parse_cipher(const char *value) #endif /* CONFIG_WEP */ else if (os_strcmp(start, "NONE") == 0) val |= WPA_CIPHER_NONE; +#ifdef CONFIG_WAPI + else if (os_strcmp(start, "SMS4") == 0) + val |= WPA_CIPHER_SMS4; +#endif else if (os_strcmp(start, "GTK_NOT_USED") == 0) val |= WPA_CIPHER_GTK_NOT_USED; else if (os_strcmp(start, "AES-128-CMAC") == 0) @@ -2920,6 +2945,16 @@ int wpa_write_ciphers(char *start, char *end, int ciphers, const char *delim) return -1; pos += ret; } +#ifdef CONFIG_WAPI + if (ciphers & WPA_CIPHER_SMS4) { + ret = os_snprintf(pos, end - pos, "%sSMS4", + pos == start ? "" : delim); + if (os_snprintf_error(end - pos, ret)) { + return -1; + } + pos += ret; + } +#endif return pos - start; } diff --git a/wpa_supplicant-2.9_standard/src/common/wpa_common.h b/wpa_supplicant-2.9_standard/src/common/wpa_common.h index b83228f..7868b35 100644 --- a/wpa_supplicant-2.9_standard/src/common/wpa_common.h +++ b/wpa_supplicant-2.9_standard/src/common/wpa_common.h @@ -112,6 +112,7 @@ WPA_CIPHER_BIP_CMAC_256) #define RSN_CIPHER_SUITE_CMIC RSN_SELECTOR(0x00, 0x40, 0x96, 2) /* KRK is defined for nl80211 use only */ #define RSN_CIPHER_SUITE_KRK RSN_SELECTOR(0x00, 0x40, 0x96, 255) +#define WLAN_CIPHER_SUITE_SMS4 0x00147201 /* EAPOL-Key Key Data Encapsulation * GroupKey and PeerKey require encryption, otherwise, encryption is optional. diff --git a/wpa_supplicant-2.9_standard/src/drivers/driver.h b/wpa_supplicant-2.9_standard/src/drivers/driver.h index 12b3d77..baae5b8 100644 --- a/wpa_supplicant-2.9_standard/src/drivers/driver.h +++ b/wpa_supplicant-2.9_standard/src/drivers/driver.h @@ -313,6 +313,10 @@ struct hostapd_hw_modes { #define IEEE80211_CAP_DMG_PBSS 0x0002 /* Tx by: PCP */ #define IEEE80211_CAP_DMG_AP 0x0003 /* Tx by: AP */ +#ifdef CONFIG_WAPI +#define SSID_MAX_WAPI_IE_LEN 100 +#endif + #define WPA_SCAN_QUAL_INVALID BIT(0) #define WPA_SCAN_NOISE_INVALID BIT(1) #define WPA_SCAN_LEVEL_INVALID BIT(2) @@ -374,6 +378,10 @@ struct wpa_scan_res { int legacyGO; #endif size_t ie_len; +#ifdef CONFIG_WAPI + u8 wapi_ie[SSID_MAX_WAPI_IE_LEN]; + size_t wapi_ie_len; +#endif size_t beacon_ie_len; /* Followed by ie_len + beacon_ie_len octets of IE data */ }; diff --git a/wpa_supplicant-2.9_standard/src/drivers/driver_nl80211.c b/wpa_supplicant-2.9_standard/src/drivers/driver_nl80211.c index 49e5291..ec12ad8 100644 --- a/wpa_supplicant-2.9_standard/src/drivers/driver_nl80211.c +++ b/wpa_supplicant-2.9_standard/src/drivers/driver_nl80211.c @@ -3130,6 +3130,10 @@ static u32 wpa_alg_to_cipher_suite(enum wpa_alg alg, size_t key_len) static u32 wpa_cipher_to_cipher_suite(unsigned int cipher) { switch (cipher) { +#ifdef CONFIG_WAPI + case WPA_CIPHER_SMS4: + return WLAN_CIPHER_SUITE_SMS4; +#endif case WPA_CIPHER_CCMP_256: return RSN_CIPHER_SUITE_CCMP_256; case WPA_CIPHER_GCMP_256: @@ -3372,7 +3376,11 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss, goto fail; wpa_hexdump_key(MSG_DEBUG, "nl80211: KEY_DATA", key, key_len); - if (seq && seq_len) { + if (seq && seq_len +#ifdef CONFIG_WAPI + && (alg != WPA_ALG_SMS4) +#endif + ) { if (nla_put(key_msg, NL80211_KEY_SEQ, seq_len, seq)) goto fail; wpa_hexdump(MSG_DEBUG, "nl80211: KEY_SEQ", @@ -3394,7 +3402,11 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss, NL80211_KEY_NO_TX : NL80211_KEY_SET_TX)) goto fail; } else if ((key_flag & KEY_FLAG_GROUP_MASK) == - KEY_FLAG_GROUP_RX) { + KEY_FLAG_GROUP_RX +#ifdef CONFIG_WAPI + && alg != WPA_ALG_SMS4 +#endif + ) { wpa_printf(MSG_DEBUG, " RSN IBSS RX GTK"); if (nla_put_u32(key_msg, NL80211_KEY_TYPE, NL80211_KEYTYPE_GROUP)) @@ -3567,6 +3579,11 @@ static int nl80211_set_conn_keys(struct wpa_driver_associate_params *params, if (params->pairwise_suite && params->pairwise_suite != WPA_CIPHER_NONE) privacy = 1; +#ifdef CONFIG_WAPI + if (params->pairwise_suite && + params->pairwise_suite == WPA_CIPHER_SMS4) + privacy = 0; +#endif if (!privacy) return 0; @@ -6470,6 +6487,13 @@ static int wpa_driver_nl80211_try_connect( } type = get_nl_auth_type(params->auth_alg); +#ifdef CONFIG_WAPI + if (type == NL80211_AUTHTYPE_MAX) { + if (params->wpa_ie[0] == WLAN_EID_WAPI) { + type = NL80211_AUTHTYPE_OPEN_SYSTEM; + } + } +#endif wpa_printf(MSG_DEBUG, " * Auth Type %d", type); if (type == NL80211_AUTHTYPE_MAX || nla_put_u32(msg, NL80211_ATTR_AUTH_TYPE, type)) diff --git a/wpa_supplicant-2.9_standard/src/drivers/driver_nl80211_capa.c b/wpa_supplicant-2.9_standard/src/drivers/driver_nl80211_capa.c index e42fb28..37cd317 100644 --- a/wpa_supplicant-2.9_standard/src/drivers/driver_nl80211_capa.c +++ b/wpa_supplicant-2.9_standard/src/drivers/driver_nl80211_capa.c @@ -1348,6 +1348,9 @@ int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv) WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK | WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B | WPA_DRIVER_CAPA_KEY_MGMT_OWE | +#ifdef CONFIG_WAPI + WPA_DRIVER_CAPA_KEY_MGMT_WAPI_PSK | +#endif WPA_DRIVER_CAPA_KEY_MGMT_DPP; if (drv->capa.enc & (WPA_DRIVER_CAPA_ENC_CCMP_256 | diff --git a/wpa_supplicant-2.9_standard/src/l2_packet/l2_packet.h b/wpa_supplicant-2.9_standard/src/l2_packet/l2_packet.h index 6a86280..24898e3 100644 --- a/wpa_supplicant-2.9_standard/src/l2_packet/l2_packet.h +++ b/wpa_supplicant-2.9_standard/src/l2_packet/l2_packet.h @@ -15,6 +15,12 @@ #ifndef L2_PACKET_H #define L2_PACKET_H +#ifdef CONFIG_WAPI +#ifndef ETH_P_WAI +#define ETH_P_WAI 0x88b4 +#endif +#endif /* WAPI */ + /** * struct l2_packet_data - Internal l2_packet data structure * diff --git a/wpa_supplicant-2.9_standard/src/l2_packet/l2_packet_linux.c b/wpa_supplicant-2.9_standard/src/l2_packet/l2_packet_linux.c index 68239e1..59381ab 100755 --- a/wpa_supplicant-2.9_standard/src/l2_packet/l2_packet_linux.c +++ b/wpa_supplicant-2.9_standard/src/l2_packet/l2_packet_linux.c @@ -20,6 +20,10 @@ #ifdef CONFIG_DRIVER_HDF #include "securec.h" #endif +#ifdef CONFIG_WAPI +#include "wpa_supplicant_i.h" +#include "securec.h" +#endif struct l2_packet_data { int fd; /* packet socket for EAPOL frames */ @@ -117,6 +121,12 @@ int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr) int l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto, const u8 *buf, size_t len) { +#ifdef CONFIG_WAPI + u8 txbuf[2312] = {0}; + u8 *pos = txbuf; + int ret_s; + int protocol_len = 2; +#endif int ret; if (TEST_FAIL()) @@ -139,9 +149,42 @@ int l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto, ll.sll_ifindex = l2->ifindex; ll.sll_protocol = htons(proto); ll.sll_halen = ETH_ALEN; +#ifdef CONFIG_WAPI + if (proto == ETH_P_WAI) { + ret_s = memcpy_s(pos, ETH_ALEN, dst_addr, ETH_ALEN); + if (ret_s != EOK) { + wpa_printf(MSG_ERROR, "dst_addr memcpy failed, ret=%d", ret_s); + return -1; + } + pos += ETH_ALEN; + ret_s = memcpy_s(pos, ETH_ALEN, l2->own_addr, ETH_ALEN); + if (ret_s != EOK) { + wpa_printf(MSG_ERROR, "own_addr memcpy failed, ret=%d", ret_s); + return -1; + } + pos += ETH_ALEN; + ret_s = memcpy_s(pos, sizeof(pos), &ll.sll_protocol, protocol_len); + if (ret_s != EOK) { + wpa_printf(MSG_ERROR, "sll_protocol memcpy failed, ret=%d", ret_s); + return -1; + } + pos += protocol_len; + ret_s = memcpy_s(pos, len, buf, len); + if (ret_s != EOK) { + wpa_printf(MSG_ERROR, "buf memcpy failed, ret=%d", ret_s); + return -1; + } + wpa_hexdump(MSG_MSGDUMP, "txbuf", txbuf, len + ETH_HLEN); + ret = sendto(l2->fd, txbuf, len + ETH_HLEN, 0, (struct sockaddr *) &ll, sizeof(ll)); + wpa_printf(MSG_DEBUG, "l2_packet_send sendto ret = '%d'", ret); + } else { +#endif os_memcpy(ll.sll_addr, dst_addr, ETH_ALEN); ret = sendto(l2->fd, buf, len, 0, (struct sockaddr *) &ll, sizeof(ll)); +#ifdef CONFIG_WAPI + } +#endif if (ret < 0) { wpa_printf(MSG_ERROR, "l2_packet_send - sendto: %s", strerror(errno)); @@ -156,13 +199,35 @@ void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx) struct l2_packet_data *l2 = eloop_ctx; u8 buf[2300]; int res; +#ifdef CONFIG_WAPI + struct l2_ethhdr l2_hdr; + struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)l2->rx_callback_ctx; + struct l2_packet_data *l2_wapi = wpa_s->l2_wapi; + int is_wapi = 0; + int ret_s; +#endif struct sockaddr_ll ll; socklen_t fromlen; +#ifdef CONFIG_WAPI + wpa_printf(MSG_DEBUG, "l2=%p, wpa_s->l2_wapi=%p\n", l2, l2_wapi); + if (l2 == l2_wapi) { + is_wapi = 1; + ret_s = memset_s(&l2_hdr, sizeof(l2_hdr), 0, sizeof(l2_hdr)); + if (ret_s != EOK) { + wpa_printf(MSG_ERROR, "l2_hdr memset failed, ret=%d", ret_s); + return; + } + res = recvfrom(sock, buf, sizeof(buf), 0, NULL, NULL); + } else { +#endif os_memset(&ll, 0, sizeof(ll)); fromlen = sizeof(ll); res = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *) &ll, &fromlen); +#ifdef CONFIG_WAPI + } +#endif if (res < 0) { wpa_printf(MSG_DEBUG, "l2_packet_receive - recvfrom: %s", strerror(errno)); @@ -173,6 +238,27 @@ void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx) if (memcpy_s(ll.sll_addr, ETH_ALEN, buf + ETH_ALEN, ETH_ALEN) != EOK) { return; } +#endif +#ifdef CONFIG_WAPI + if (is_wapi) { + ret_s = memcpy_s(&l2_hdr, sizeof(l2_hdr), buf, ETH_HLEN); + if (ret_s != EOK) { + wpa_printf(MSG_ERROR, "buf memcpy failed, ret=%d", ret_s); + return; + } + l2_hdr.h_proto = ntohs (l2_hdr.h_proto); + res -= ETH_HLEN; + if (res > 0) { + ret_s = memmove_s(buf, sizeof(buf), (char *)buf + ETH_HLEN, res); + if (ret_s != EOK) { + wpa_printf(MSG_ERROR, "buf memmove failed, ret=%d", ret_s); + return; + } + } else { + res = 0; + } + l2->rx_callback(l2->rx_callback_ctx, l2_hdr.h_source, buf, res); + } else { #endif wpa_printf(MSG_DEBUG, "%s: src=" MACSTR_SEC " len=%d", __func__, MAC2STR_SEC(ll.sll_addr), (int) res); @@ -223,6 +309,9 @@ void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx) l2->last_from_br = 0; #endif /* CONFIG_NO_LINUX_PACKET_SOCKET_WAR */ l2->rx_callback(l2->rx_callback_ctx, ll.sll_addr, buf, res); +#ifdef CONFIG_WAPI + } +#endif } @@ -300,6 +389,11 @@ struct l2_packet_data * l2_packet_init( l2->fd_br_rx = -1; #endif /* CONFIG_NO_LINUX_PACKET_SOCKET_WAR */ +#ifdef CONFIG_WAPI + if (protocol == ETH_P_WAI) + l2->fd = socket(PF_PACKET, SOCK_RAW, htons(protocol)); + else +#endif l2->fd = socket(PF_PACKET, l2_hdr ? SOCK_RAW : SOCK_DGRAM, htons(protocol)); if (l2->fd < 0) { diff --git a/wpa_supplicant-2.9_standard/src/rsn_supp/wpa_ie.c b/wpa_supplicant-2.9_standard/src/rsn_supp/wpa_ie.c index 3ba722f..8e47748 100644 --- a/wpa_supplicant-2.9_standard/src/rsn_supp/wpa_ie.c +++ b/wpa_supplicant-2.9_standard/src/rsn_supp/wpa_ie.c @@ -88,6 +88,10 @@ static int wpa_gen_wpa_ie_wpa(u8 *wpa_ie, size_t wpa_ie_len, RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_NONE); } else if (key_mgmt == WPA_KEY_MGMT_CCKM) { RSN_SELECTOR_PUT(pos, WPA_AUTH_KEY_MGMT_CCKM); + } else if (key_mgmt == WPA_KEY_MGMT_WAPI_PSK) { + RSN_SELECTOR_PUT(pos, WPA_KEY_MGMT_WAPI_PSK); + } else if (key_mgmt == WPA_KEY_MGMT_WAPI_CERT) { + RSN_SELECTOR_PUT(pos, WPA_KEY_MGMT_WAPI_CERT); } else { wpa_printf(MSG_WARNING, "Invalid key management type (%d).", key_mgmt); diff --git a/wpa_supplicant-2.9_standard/wpa.gni b/wpa_supplicant-2.9_standard/wpa.gni index a7dc7cd..f5d7afc 100644 --- a/wpa_supplicant-2.9_standard/wpa.gni +++ b/wpa_supplicant-2.9_standard/wpa.gni @@ -15,9 +15,11 @@ declare_args() { CONFIG_CTRL_IFACE = "unix" wpa_vendor_gni = "" wpa_supplicant_vendor_ext = false + wpa_supplicant_wapi = false } WPA_ROOT_DIR = "//third_party/wpa_supplicant/wpa_supplicant-2.9_standard" print("wpa_vendor_gni =", wpa_vendor_gni) print("wpa_supplicant_vendor_ext =", wpa_supplicant_vendor_ext) +print("wpa_supplicant_wapi =", wpa_supplicant_wapi) diff --git a/wpa_supplicant-2.9_standard/wpa_supplicant/ap.c b/wpa_supplicant-2.9_standard/wpa_supplicant/ap.c index ffe263d..9459edd 100644 --- a/wpa_supplicant-2.9_standard/wpa_supplicant/ap.c +++ b/wpa_supplicant-2.9_standard/wpa_supplicant/ap.c @@ -1153,6 +1153,9 @@ void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s) wpa_s->current_ssid = NULL; eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); wpa_s->assoc_freq = 0; +#ifdef CONFIG_WAPI + wpa_s->ap_wapi_ie_len = 0; +#endif wpas_p2p_ap_deinit(wpa_s); wpa_s->ap_iface->driver_ap_teardown = !!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT); diff --git a/wpa_supplicant-2.9_standard/wpa_supplicant/bss.c b/wpa_supplicant-2.9_standard/wpa_supplicant/bss.c index 601fd73..212355f 100644 --- a/wpa_supplicant-2.9_standard/wpa_supplicant/bss.c +++ b/wpa_supplicant-2.9_standard/wpa_supplicant/bss.c @@ -444,6 +444,9 @@ static struct wpa_bss * wpa_bss_add(struct wpa_supplicant *wpa_s, { struct wpa_bss *bss; char extra[50]; +#ifdef CONFIG_WAPI + const u8 *wapi_ie; +#endif bss = os_zalloc(sizeof(*bss) + res->ie_len + res->beacon_ie_len); if (bss == NULL) @@ -460,6 +463,12 @@ static struct wpa_bss * wpa_bss_add(struct wpa_supplicant *wpa_s, bss->last_update_idx = 0xFFFFFFFF; /* Not delete bss */ } #endif /* CONFIG_MAGICLINK_PC */ +#ifdef CONFIG_WAPI + wapi_ie = wpa_scan_get_ie(res, WLAN_EID_WAPI); + if (wapi_ie) { + bss->wapi_ie_len = wapi_ie ? wapi_ie[1] + 2 : 0; + } +#endif bss->beacon_ie_len = res->beacon_ie_len; os_memcpy(bss->ies, res + 1, res->ie_len + res->beacon_ie_len); wpa_bss_set_hessid(bss); diff --git a/wpa_supplicant-2.9_standard/wpa_supplicant/bss.h b/wpa_supplicant-2.9_standard/wpa_supplicant/bss.h index 0fd8343..3f752a5 100644 --- a/wpa_supplicant-2.9_standard/wpa_supplicant/bss.h +++ b/wpa_supplicant-2.9_standard/wpa_supplicant/bss.h @@ -123,6 +123,9 @@ struct wpa_bss { size_t ie_len; /** Length of the following Beacon IE field in octets */ size_t beacon_ie_len; +#ifdef CONFIG_WAPI + size_t wapi_ie_len; +#endif /* followed by ie_len octets of IEs */ /* followed by beacon_ie_len octets of IEs */ u8 ies[]; diff --git a/wpa_supplicant-2.9_standard/wpa_supplicant/config.c b/wpa_supplicant-2.9_standard/wpa_supplicant/config.c index 844764c..f6a366d 100644 --- a/wpa_supplicant-2.9_standard/wpa_supplicant/config.c +++ b/wpa_supplicant-2.9_standard/wpa_supplicant/config.c @@ -19,6 +19,9 @@ #include "p2p/p2p.h" #include "fst/fst.h" #include "config.h" +#ifdef CONFIG_WAPI +#include "securec.h" +#endif #if !defined(CONFIG_CTRL_IFACE) && defined(CONFIG_NO_CONFIG_WRITE) @@ -467,6 +470,53 @@ static int wpa_config_parse_bssid_blacklist(const struct parse_data *data, } +#ifdef CONFIG_WAPI +static int wpa_config_parse_wapi_psk(const struct parse_data *data, + struct wpa_ssid *ssid, int line, + const char *value) +{ + int min_len = 8; + int max_len = 64; + if (*value == '"') { + value++; + size_t len; + const char *pos; + pos = os_strrchr(value, '"'); + len = pos ? (pos - value) : os_strlen(value); + if (len < min_len || len > max_len) { + wpa_printf(MSG_ERROR,"Invalid passphrase " + "length %lu (expected: 8...64) '%s'.", (unsigned long) len, value); + return -1; + } + + if (ssid->wapi_psk && os_strlen(ssid->wapi_psk) == len && + memcmp(ssid->wapi_psk, value, len) == EOK) { + return 0; + } + os_free(ssid->wapi_psk); + ssid->wapi_psk = os_malloc(len + 1); + if ((ssid->wapi_psk != NULL) && (memcpy_s(ssid->wapi_psk, len, value, len) == EOK)) { + ssid->wapi_psk[len] = '\0'; + return 0; + } else { + return -1; + } + } + wpa_printf(MSG_ERROR, "read wapi psk failed"); + return -1; +} + +static char *wpa_config_write_wapi_psk(const struct parse_data *data, + struct wpa_ssid *ssid) +{ + if (ssid->wapi_psk) + return wpa_config_write_string_ascii((const u8 *)ssid->wapi_psk, + os_strlen(ssid->wapi_psk)); + + return NULL; +} +#endif + #ifndef NO_CONFIG_WRITE static char * wpa_config_write_bssid_ignore(const struct parse_data *data, @@ -679,6 +729,10 @@ static int wpa_config_parse_proto(const struct parse_data *data, else if (os_strcmp(start, "RSN") == 0 || os_strcmp(start, "WPA2") == 0) val |= WPA_PROTO_RSN; +#ifdef CONFIG_WAPI + else if (os_strcmp(start, "WAPI") == 0) + val |= WPA_PROTO_WAPI; +#endif else if (os_strcmp(start, "OSEN") == 0) val |= WPA_PROTO_OSEN; else { @@ -734,6 +788,15 @@ static char * wpa_config_write_proto(const struct parse_data *data, return buf; pos += ret; } +#ifdef CONFIG_WAPI + if (ssid->proto & WPA_PROTO_WAPI) { + ret = os_snprintf(pos, end - pos, "%sWAPI", + pos == buf ? "" : " "); + if (os_snprintf_error(end - pos, ret)) + return buf; + pos += ret; + } +#endif if (ssid->proto & WPA_PROTO_OSEN) { ret = os_snprintf(pos, end - pos, "%sOSEN", @@ -785,6 +848,12 @@ static int wpa_config_parse_key_mgmt(const struct parse_data *data, val |= WPA_KEY_MGMT_NONE; else if (os_strcmp(start, "WPA-NONE") == 0) val |= WPA_KEY_MGMT_WPA_NONE; +#ifdef CONFIG_WAPI + else if (os_strcmp(start, "WAPI-CERT") == 0) + val |= WPA_KEY_MGMT_WAPI_CERT; + else if (os_strcmp(start, "WAPI-PSK") == 0) + val |= WPA_KEY_MGMT_WAPI_PSK; +#endif #ifdef CONFIG_IEEE80211R else if (os_strcmp(start, "FT-PSK") == 0) val |= WPA_KEY_MGMT_FT_PSK; @@ -863,6 +932,14 @@ static int wpa_config_parse_key_mgmt(const struct parse_data *data, return 1; wpa_printf(MSG_MSGDUMP, "key_mgmt: 0x%x", val); ssid->key_mgmt = val; +#ifdef CONFIG_WAPI + if ((ssid->key_mgmt & WPA_KEY_MGMT_WAPI_PSK) && (ssid->wapi != WAPI_TYPE_PSK)) { + ssid->wapi = WAPI_TYPE_PSK; + } + if ((ssid->key_mgmt & WPA_KEY_MGMT_WAPI_CERT) && (ssid->wapi != WAPI_TYPE_CERT)) { + ssid->wapi = WAPI_TYPE_CERT; + } +#endif return errors ? -1 : 0; } @@ -929,6 +1006,28 @@ static char * wpa_config_write_key_mgmt(const struct parse_data *data, pos += ret; } +#ifdef CONFIG_WAPI + if (ssid->key_mgmt & WPA_KEY_MGMT_WAPI_CERT) { + ret = os_snprintf(pos, end - pos, "%sWAPI-CERT", + pos == buf ? "" : " "); + if (os_snprintf_error(end - pos, ret)) { + end[-1] = '\0'; + return buf; + } + pos += ret; + } + + if (ssid->key_mgmt & WPA_KEY_MGMT_WAPI_PSK) { + ret = os_snprintf(pos, end - pos, "%sWAPI-PSK", + pos == buf ? "" : " "); + if (os_snprintf_error(end - pos, ret)) { + end[-1] = '\0'; + return buf; + } + pos += ret; + } +#endif + #ifdef CONFIG_IEEE80211R if (ssid->key_mgmt & WPA_KEY_MGMT_FT_PSK) { ret = os_snprintf(pos, end - pos, "%sFT-PSK", @@ -1178,7 +1277,11 @@ static int wpa_config_parse_pairwise(const struct parse_data *data, val = wpa_config_parse_cipher(line, value); if (val == -1) return -1; - if (val & ~WPA_ALLOWED_PAIRWISE_CIPHERS) { + if (val & ~(WPA_ALLOWED_PAIRWISE_CIPHERS +#ifdef CONFIG_WAPI + | WPA_CIPHER_SMS4 +#endif + )) { wpa_printf(MSG_ERROR, "Line %d: not allowed pairwise cipher " "(0x%x).", line, val); return -1; @@ -1216,7 +1319,11 @@ static int wpa_config_parse_group(const struct parse_data *data, */ val &= ~(WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40); - if (val & ~WPA_ALLOWED_GROUP_CIPHERS) { + if (val & ~(WPA_ALLOWED_GROUP_CIPHERS +#ifdef CONFIG_WAPI + | WPA_CIPHER_SMS4 +#endif + )) { wpa_printf(MSG_ERROR, "Line %d: not allowed group cipher " "(0x%x).", line, val); return -1; @@ -2433,6 +2540,14 @@ static const struct parse_data ssid_fields[] = { { FUNC(auth_alg) }, { FUNC(scan_freq) }, { FUNC(freq_list) }, +#ifdef CONFIG_WAPI + { INT(wapi) }, + { INT(psk_key_type) }, + { FUNC_KEY(wapi_psk) }, + { STR(wapi_user_sel_cert) }, + { STR(wapi_ca_cert) }, + { INT(wapi_user_cert_mode) }, +#endif { INT_RANGE(ht, 0, 1) }, { INT_RANGE(vht, 0, 1) }, { INT_RANGE(ht40, -1, 1) }, @@ -2827,6 +2942,11 @@ void wpa_config_free_ssid(struct wpa_ssid *ssid) os_free(ssid->scan_freq); os_free(ssid->freq_list); os_free(ssid->bgscan); +#ifdef CONFIG_WAPI + os_free(ssid->wapi_psk); + os_free(ssid->wapi_user_sel_cert); + os_free(ssid->wapi_ca_cert); +#endif os_free(ssid->p2p_client_list); os_free(ssid->bssid_ignore); os_free(ssid->bssid_accept); @@ -3119,6 +3239,9 @@ void wpa_config_set_network_defaults(struct wpa_ssid *ssid) ssid->eap.fragment_size = DEFAULT_FRAGMENT_SIZE; ssid->eap.sim_num = DEFAULT_USER_SELECTED_SIM; #endif /* IEEE8021X_EAPOL */ +#ifdef CONFIG_WAPI + ssid->wapi = WAPI_TYPE_NONE; +#endif #ifdef CONFIG_MESH ssid->dot11MeshMaxRetries = DEFAULT_MESH_MAX_RETRIES; ssid->dot11MeshRetryTimeout = DEFAULT_MESH_RETRY_TIMEOUT; @@ -3224,6 +3347,7 @@ int wpa_config_set(struct wpa_ssid *ssid, const char *var, const char *value, } ret = -1; } + #ifdef CONFIG_SAE if (os_strcmp(var, "ssid") == 0 || os_strcmp(var, "psk") == 0 || diff --git a/wpa_supplicant-2.9_standard/wpa_supplicant/config_file.c b/wpa_supplicant-2.9_standard/wpa_supplicant/config_file.c index 5866d7b..65168e7 100644 --- a/wpa_supplicant-2.9_standard/wpa_supplicant/config_file.c +++ b/wpa_supplicant-2.9_standard/wpa_supplicant/config_file.c @@ -30,6 +30,42 @@ static int wpa_config_validate_network(struct wpa_ssid *ssid, int line) { int errors = 0; +#ifdef CONFIG_WAPI + if ((ssid->wapi != WAPI_TYPE_NONE) && + (ssid->key_mgmt != WPA_KEY_MGMT_WAPI_PSK) && (ssid->key_mgmt != WPA_KEY_MGMT_WAPI_CERT)) { + if (ssid->wapi == WAPI_TYPE_CERT) { + ssid->key_mgmt = WPA_KEY_MGMT_WAPI_CERT; + } else if (ssid->wapi == WAPI_TYPE_PSK) { + ssid->key_mgmt = WPA_KEY_MGMT_WAPI_PSK; + } else { + wpa_printf(MSG_ERROR, "unknown wapi policy %d", ssid->wapi); + errors++; + } + if (ssid->group_cipher != WPA_CIPHER_SMS4) { + ssid->group_cipher = WPA_CIPHER_SMS4; + } + if (ssid->pairwise_cipher != WPA_CIPHER_SMS4) { + ssid->pairwise_cipher = WPA_CIPHER_SMS4; + } + } else if ((ssid->wapi == WAPI_TYPE_NONE) && + ((ssid->key_mgmt == WPA_KEY_MGMT_WAPI_PSK) || (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_CERT))) { + if (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_CERT) { + ssid->proto = WPA_PROTO_WAPI; + ssid->wapi = WAPI_TYPE_CERT; + } + if (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_PSK) { + ssid->proto = WPA_PROTO_WAPI; + ssid->wapi = WAPI_TYPE_PSK; + } + if (ssid->group_cipher != WPA_CIPHER_SMS4) { + ssid->group_cipher = WPA_CIPHER_SMS4; + } + if (ssid->pairwise_cipher != WPA_CIPHER_SMS4) { + ssid->pairwise_cipher = WPA_CIPHER_SMS4; + } + } else { +#endif + if (ssid->passphrase) { if (ssid->psk_set) { wpa_printf(MSG_ERROR, "Line %d: both PSK and " @@ -52,7 +88,9 @@ static int wpa_config_validate_network(struct wpa_ssid *ssid, int line) "cipher", line); ssid->group_cipher &= ~WPA_CIPHER_CCMP; } - +#ifdef CONFIG_WAPI + } +#endif if (ssid->mode == WPAS_MODE_MESH && (ssid->key_mgmt != WPA_KEY_MGMT_NONE && ssid->key_mgmt != WPA_KEY_MGMT_SAE)) { @@ -678,6 +716,18 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) write_int(f, "sae_pwe", ssid->sae_pwe, DEFAULT_SAE_PWE); write_proto(f, ssid); write_key_mgmt(f, ssid); +#ifdef CONFIG_WAPI + INT(wapi); + if ((ssid->wapi == WAPI_TYPE_PSK) || (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_PSK)) { + INT(psk_key_type); + STR(wapi_psk); + } + if ((ssid->wapi == WAPI_TYPE_CERT) || (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_CERT)) { + STR(wapi_user_sel_cert); + STR(wapi_ca_cert); + INT(wapi_user_cert_mode); + } +#endif INT_DEF(bg_scan_period, DEFAULT_BG_SCAN_PERIOD); write_pairwise(f, ssid); write_group(f, ssid); diff --git a/wpa_supplicant-2.9_standard/wpa_supplicant/config_ssid.h b/wpa_supplicant-2.9_standard/wpa_supplicant/config_ssid.h index 724534d..a9f4421 100644 --- a/wpa_supplicant-2.9_standard/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant-2.9_standard/wpa_supplicant/config_ssid.h @@ -17,6 +17,20 @@ #define DEFAULT_EAP_WORKAROUND ((unsigned int) -1) #define DEFAULT_EAPOL_FLAGS (EAPOL_FLAG_REQUIRE_KEY_UNICAST | \ EAPOL_FLAG_REQUIRE_KEY_BROADCAST) +#ifdef CONFIG_WAPI +#define DEFAULT_WAPI_USER_CERT_MODE 1 +#define DEFAULT_PROTO (WPA_PROTO_WPA | WPA_PROTO_RSN | WPA_PROTO_WAPI) +#define DEFAULT_KEY_MGMT (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_IEEE8021X | \ + WPA_KEY_MGMT_WAPI_PSK | WPA_KEY_MGMT_WAPI_CERT) +#define DEFAULT_PAIRWISE (WPA_CIPHER_CCMP | WPA_CIPHER_TKIP | WPA_CIPHER_SMS4) +#define DEFAULT_GROUP (WPA_CIPHER_CCMP | WPA_CIPHER_TKIP | \ + WPA_CIPHER_SMS4) +enum WAPI_TYPE { + WAPI_TYPE_NONE = 0, + WAPI_TYPE_PSK = 7, + WAPI_TYPE_CERT = 11, +}; +#else #define DEFAULT_PROTO (WPA_PROTO_WPA | WPA_PROTO_RSN) #define DEFAULT_KEY_MGMT (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_IEEE8021X) #ifdef CONFIG_NO_TKIP @@ -26,6 +40,7 @@ #define DEFAULT_PAIRWISE (WPA_CIPHER_CCMP | WPA_CIPHER_TKIP) #define DEFAULT_GROUP (WPA_CIPHER_CCMP | WPA_CIPHER_TKIP) #endif /* CONFIG_NO_TKIP */ +#endif /* CONFIG_WAPI */ #define DEFAULT_FRAGMENT_SIZE 1398 #define DEFAULT_BG_SCAN_PERIOD -1 @@ -500,6 +515,15 @@ struct wpa_ssid { * will be used instead of this configured value. */ int frequency; +#ifdef CONFIG_WAPI + int wapi; + int wapi_ie_len; + int psk_key_type; + char *wapi_psk; + int wapi_user_cert_mode; + char *wapi_user_sel_cert; + char *wapi_ca_cert; +#endif /** * enable_edmg - Enable EDMG feature in STA/AP mode diff --git a/wpa_supplicant-2.9_standard/wpa_supplicant/ctrl_iface.c b/wpa_supplicant-2.9_standard/wpa_supplicant/ctrl_iface.c index dc96e94..c707992 100644 --- a/wpa_supplicant-2.9_standard/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant-2.9_standard/wpa_supplicant/ctrl_iface.c @@ -64,6 +64,10 @@ #ifdef CONFIG_VENDOR_EXT #include "vendor_ext.h" #endif +#ifdef CONFIG_WAPI +#include "wapi_asue_i.h" +#include "securec.h" +#endif #ifdef __NetBSD__ #include @@ -2205,6 +2209,61 @@ static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s, #endif /* IEEE8021X_EAPOL */ } +#ifdef CONFIG_WAPI +static const char* wapi_key_mgmt_txt(int key_mgmt) +{ + switch (key_mgmt) { + case WPA_KEY_MGMT_WAPI_PSK: + return "WAPI-PSK"; + case WPA_KEY_MGMT_WAPI_CERT: + return "WAPI-CERT"; + default: + return "UNKNOWN"; + } +} + +static int wapi_get_cipher_key_mgmt(unsigned int key_mgmt, char *buf, size_t buflen, int verbose) +{ + char *pos = buf, *end = buf + buflen; + int ret; + + ret = os_snprintf(pos, end - pos, + "pairwise_cipher=SMS4\n" + "group_cipher=SMS4\n" + "key_mgmt=%s\n", + wapi_key_mgmt_txt(key_mgmt)); + if (ret < 0 || ret >= end - pos) + return pos - buf; + pos += ret; + return pos - buf; +} + +static const char* wapi_psk_type_txt(int psk_key_type) +{ + switch (psk_key_type) { + case KEY_TYPE_ASCII: + return "ASCII"; + case KEY_TYPE_HEX: + return "HEX"; + default: + return "UNKNOWN"; + } +} + +static int wapi_get_psk_key_type(int key_type, char *buf, size_t buflen, int verbose) +{ + char *pos = buf, *end = buf + buflen; + int ret; + + ret = os_snprintf(pos, end - pos, + "psk_key_type=%s\n", + wapi_psk_type_txt(key_type)); + if (ret < 0 || ret >= end - pos) + return pos - buf; + pos += ret; + return pos - buf; +} +#endif int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s, const char *params, @@ -2321,7 +2380,15 @@ int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s, return pos - buf; pos += ret; } - +#ifdef CONFIG_WAPI + if (ssid->wapi) { + wpa_printf(MSG_DEBUG, "wapi_get_cipher_key_mgmt"); + pos += wapi_get_cipher_key_mgmt(ssid->key_mgmt, pos, end - pos, verbose); + if (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_PSK) + pos += wapi_get_psk_key_type(ssid->psk_key_type, pos, + end - pos, verbose); + } else +#endif #ifdef CONFIG_AP if (wpa_s->ap_iface) { pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos, @@ -2764,6 +2831,69 @@ static char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher) } +#ifdef CONFIG_WAPI +#define WAPIIE_ELEMENT_ID_LEN 1 +#define WAPIIE_LENGTH_LEN 1 +#define WAPIIE_VERSION_LEN 2 +#define WAPIIE_AKM_CNT_LEN 2 +#define WAPIIE_AKM_SUIT_LEN 4 +#define WAPIIE_AKM_SUIT_CERT 0x00147201 +#define WAPIIE_AKM_SUIT_PSK 0x00147202 +#define WAPI_HEAD_LEN (WAPIIE_ELEMENT_ID_LEN + WAPIIE_LENGTH_LEN + WAPIIE_VERSION_LEN + 2) +#define AKM_SUIT_CNT_MAX 2 +#define SHIFT_OPT8 8 +#define MY_GET32(p) ((((*p) << 24) & 0xff000000) | (((*(p+1)) << 16) & 0xff0000) | \ + (((*(p+2)) << 8) & 0xff00) | ((*(p+3)) & 0xff)) + +static char *wpa_supplicant_wapi_ie_txt(char *pos, char *end, + const u8 *ie, size_t ie_len) +{ + int i, ret; + u8 *ie_hdr = (u8 *)ie, *p_akm_auit_cnt, *p_akm; + int akm_suit_cnt = 0; + char *old_pos = pos; + + if (ie_len < WAPI_HEAD_LEN) { + wpa_printf(MSG_ERROR, "ie_len is too short, ie_len = %zu(<6)", ie_len); + return old_pos; + } + + p_akm_auit_cnt = ie_hdr + (WAPIIE_ELEMENT_ID_LEN + WAPIIE_LENGTH_LEN + WAPIIE_VERSION_LEN); + akm_suit_cnt = ((*p_akm_auit_cnt) | ((*(p_akm_auit_cnt + 1) << SHIFT_OPT8) & 0xff00)) & 0xffff; + if (akm_suit_cnt > AKM_SUIT_CNT_MAX) { + wpa_printf(MSG_ERROR, "akm_suit_cnt: %d is error!", akm_suit_cnt); + return old_pos; + } + if (ie_len < (size_t)(WAPI_HEAD_LEN + akm_suit_cnt * WAPIIE_AKM_SUIT_LEN)) { + wpa_printf(MSG_ERROR, "ie_len is too short, ie_len = %zu(<6), need more than: %d", + ie_len, (WAPI_HEAD_LEN + akm_suit_cnt * WAPIIE_AKM_SUIT_LEN)); + return old_pos; + } + p_akm = (p_akm_auit_cnt + WAPIIE_AKM_CNT_LEN); + for (i = 0; i < akm_suit_cnt; i++) { + if (MY_GET32(p_akm) == WAPIIE_AKM_SUIT_PSK) { + wpa_printf(MSG_DEBUG, "AKM_SUIT is : [WAPI-PSK]"); + ret = snprintf_s(pos, end - pos, end - pos - 1, "[WAPI-KEY]"); + if (os_snprintf_error(end - pos, ret)) { + wpa_printf(MSG_ERROR, "snprintf failed."); + return pos; + } + pos += ret; + } else if (MY_GET32(p_akm) == WAPIIE_AKM_SUIT_CERT) { + wpa_printf(MSG_DEBUG, "AKM_SUIT is : [WAPI-CERT]"); + ret = snprintf_s(pos, end - pos, end - pos - 1, "[WAPI-CERT]"); + if (os_snprintf_error(end - pos, ret)) { + wpa_printf(MSG_ERROR, "snprintf failed."); + return pos; + } + pos += ret; + } + p_akm += WAPIIE_AKM_SUIT_LEN; + } + return pos; +} +#endif + static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto, const u8 *ie, size_t ie_len) { @@ -3003,6 +3133,10 @@ static int wpa_supplicant_ctrl_iface_scan_result( #ifdef CONFIG_OPEN_HARMONY_PATCH const u8 *infoEle; #endif +#ifdef CONFIG_WAPI + const u8 *ie3; +#endif + wpa_printf(MSG_INFO, "enter wpa_supplicant_ctrl_iface_scan_result"); mesh = wpa_bss_get_ie(bss, WLAN_EID_MESH_ID); p2p = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE); @@ -3029,6 +3163,16 @@ static int wpa_supplicant_ctrl_iface_scan_result( pos = wpa_supplicant_ie_txt(pos, end, mesh ? "RSN" : "WPA2", ie2, 2 + ie2[1]); } +#ifdef CONFIG_WAPI + ie3 = wpa_bss_get_ie(bss, WLAN_EID_WAPI); + if (ie3) { + char *pos_b = pos; + pos = wpa_supplicant_wapi_ie_txt(pos, end, ie3, 2 + ie3[1]); + if (pos == pos_b) { + ie3 = NULL; + } + } +#endif rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX); if (ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SAE_H2E)) { ret = os_snprintf(pos, end - pos, "[SAE-H2E]"); @@ -3055,7 +3199,11 @@ static int wpa_supplicant_ctrl_iface_scan_result( pos += ret; } pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss); +#ifdef CONFIG_WAPI + if (!ie && !ie2 && !ie3 && !osen_ie && (bss->caps & IEEE80211_CAP_PRIVACY)) { +#else if (!ie && !ie2 && !osen_ie && (bss->caps & IEEE80211_CAP_PRIVACY)) { +#endif ret = os_snprintf(pos, end - pos, "[WEP]"); if (os_snprintf_error(end - pos, ret)) return -1; @@ -3119,6 +3267,14 @@ static int wpa_supplicant_ctrl_iface_scan_result( return -1; pos += ret; } +#ifdef CONFIG_WAPI + if (!ie && !ie2 && !ie3) { + ret = os_snprintf(pos, end - pos, "\t"); + if (os_snprintf_error(end - pos, ret)) + return pos - buf; + pos += ret; + } +#endif #ifdef CONFIG_HS20 if (wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE) && ie2) { ret = os_snprintf(pos, end - pos, "[HS20]"); @@ -5047,6 +5203,9 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, int ret; char *pos, *end; const u8 *ie, *ie2, *osen_ie, *mesh, *owe, *rsnxe; +#ifdef CONFIG_WAPI + const u8 *ie3; +#endif pos = buf; end = buf + buflen; @@ -5183,6 +5342,23 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, if (osen_ie) pos = wpa_supplicant_ie_txt(pos, end, "OSEN", osen_ie, 2 + osen_ie[1]); +#ifdef CONFIG_WAPI + ie3 = wpa_bss_get_ie(bss, WLAN_EID_WAPI); + if (ie3) { + char *pos_b = pos; + pos = wpa_supplicant_wapi_ie_txt(pos, end, ie3, 2 + ie3[1]); + if (pos == pos_b) { + ie3 = NULL; + } + } + if (!ie && !ie2 && !ie3 && (bss->caps & IEEE80211_CAP_PRIVACY)) { + ret = os_snprintf(pos, end - pos, "[WEP]"); + if (os_snprintf_error(end - pos, ret)) { + return -1; + } + pos += ret; + } +#endif owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE); if (owe) { ret = os_snprintf( diff --git a/wpa_supplicant-2.9_standard/wpa_supplicant/driver_i.h b/wpa_supplicant-2.9_standard/wpa_supplicant/driver_i.h index 180702c..d26fa63 100644 --- a/wpa_supplicant-2.9_standard/wpa_supplicant/driver_i.h +++ b/wpa_supplicant-2.9_standard/wpa_supplicant/driver_i.h @@ -199,6 +199,31 @@ static inline int wpa_drv_get_seqnum(struct wpa_supplicant *wpa_s, return -1; } +#ifdef CONFIG_WAPI +static inline int wpa_drv_set_wapi_key(struct wpa_supplicant *wpa_s, enum wpa_alg alg, + const u8 *addr, int key_idx, int set_tx, + const u8 *seq, size_t seq_len, + const u8 *key, size_t key_len, enum key_flag key_flag) +{ + struct wpa_driver_set_key_params params; + os_memset(¶ms, 0, sizeof(params)); + params.ifname = wpa_s->ifname; + params.alg = alg; + params.addr = addr; + params.set_tx = set_tx; + params.seq = seq; + params.seq_len = seq_len; + params.key_idx = key_idx; + params.key = key; + params.key_len = key_len; + params.key_flag = key_flag; + if (wpa_s->driver->set_key) { + return wpa_s->driver->set_key(wpa_s->drv_priv, ¶ms); + } + return -1; +} +#endif + static inline int wpa_drv_sta_deauth(struct wpa_supplicant *wpa_s, const u8 *addr, u16 reason_code) { diff --git a/wpa_supplicant-2.9_standard/wpa_supplicant/events.c b/wpa_supplicant-2.9_standard/wpa_supplicant/events.c index b3de572..d27f518 100644 --- a/wpa_supplicant-2.9_standard/wpa_supplicant/events.c +++ b/wpa_supplicant-2.9_standard/wpa_supplicant/events.c @@ -54,6 +54,10 @@ #ifdef CONFIG_VENDOR_EXT #include "vendor_ext.h" #endif +#ifdef CONFIG_WAPI +#include "wapi_asue_i.h" +extern void wpas_connect_work_done(struct wpa_supplicant *wpa_s); +#endif #define MAX_OWE_TRANSITION_BSS_SELECT_COUNT 5 @@ -621,11 +625,41 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s, #ifdef CONFIG_WEP int wep_ok; #endif /* CONFIG_WEP */ - +#ifdef CONFIG_WAPI + const u8 *wapi_ie; + u8 wapi_ie_len; + u8 wapi_type_index = 9; +#endif ret = wpas_wps_ssid_bss_match(wpa_s, ssid, bss); if (ret >= 0) return ret; +#ifdef CONFIG_WAPI + wapi_ie = wpa_bss_get_ie(bss, WLAN_EID_WAPI); + if (!wapi_ie) { + wpa_printf(MSG_ERROR, "%s : wapi is null", __func__); + return -1; + } + while ((ssid->proto & WPA_PROTO_WAPI) && wapi_ie) { + proto_match++; + wapi_ie_len = wapi_ie ? wapi_ie[1] + 2 : 0; + bss->wapi_ie_len = wapi_ie_len; + ssid->wapi_ie_len = wapi_ie_len; + wpa_printf(MSG_DEBUG, "ssid->wapi=%x, ssid->key_mgmt=%x bss->wapi_ie_len=%d wapi_ie_9 = %d", + ssid->wapi, ssid->key_mgmt, (int)bss->wapi_ie_len, (int)wapi_ie[wapi_type_index]); + if (((ssid->wapi == WAPI_TYPE_PSK) || (ssid->key_mgmt & WPA_KEY_MGMT_WAPI_PSK)) && + (wapi_ie[wapi_type_index] == AUTH_TYPE_WAPI_PSK)) { + wpa_printf(MSG_DEBUG, "WAPI PSK network is selected based on WAPI IE"); + return 1; + } + if (((ssid->wapi == WAPI_TYPE_CERT) || (ssid->key_mgmt & WPA_KEY_MGMT_WAPI_CERT)) && + (wapi_ie[wapi_type_index] == AUTH_TYPE_WAPI_CERT)) { + wpa_printf(MSG_DEBUG, "WAPI CERT network is selected based on WAPI IE"); + return 1; + } + break; + } +#endif #ifdef CONFIG_WEP /* Allow TSN if local configuration accepts WEP use without WPA/WPA2 */ wep_ok = !wpa_key_mgmt_wpa(ssid->key_mgmt) && @@ -823,6 +857,15 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s, } #endif /* CONFIG_OWE */ +#ifdef CONFIG_WAPI + if ((ssid->proto & (WPA_PROTO_WPA | WPA_PROTO_RSN | WPA_PROTO_WAPI)) && + wpa_key_mgmt_wpa(ssid->key_mgmt) && proto_match == 0) { + if (debug_print) + wpa_dbg(wpa_s, MSG_DEBUG, + " skip - no WPA/RSN/WAPI proto match"); + return 0; + } +#else if ((ssid->proto & (WPA_PROTO_WPA | WPA_PROTO_RSN)) && wpa_key_mgmt_wpa(ssid->key_mgmt) && proto_match == 0) { if (debug_print) @@ -830,6 +873,7 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s, " skip - no WPA/RSN proto match"); return 0; } +#endif if ((ssid->key_mgmt & WPA_KEY_MGMT_OSEN) && wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE)) { @@ -1216,6 +1260,9 @@ static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, #ifdef CONFIG_SAE u8 rsnxe_capa = 0; #endif /* CONFIG_SAE */ +#ifdef CONFIG_WAPI + u8 wapi_ie_len; +#endif const u8 *ie; ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); @@ -1234,7 +1281,14 @@ static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, rsnxe_capa = ie[2]; #endif /* CONFIG_SAE */ +#ifdef CONFIG_WAPI + ie = wpa_bss_get_ie(bss, WLAN_EID_WAPI); + wapi_ie_len = ie ? ie[1] : 0; + wpa |= ie && ie[1]; + check_ssid = wpa || ssid->ssid_len > 0 || wapi_ie_len > 0; +#else check_ssid = wpa || ssid->ssid_len > 0; +#endif if (wpas_network_disabled(wpa_s, ssid)) { if (debug_print) @@ -1317,6 +1371,10 @@ static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, !(ssid->key_mgmt & WPA_KEY_MGMT_NONE) && !(ssid->key_mgmt & WPA_KEY_MGMT_WPS) && !(ssid->key_mgmt & WPA_KEY_MGMT_OWE) && +#ifdef CONFIG_WAPI + !(ssid->key_mgmt & WPA_KEY_MGMT_WAPI_PSK) && + !(ssid->key_mgmt & WPA_KEY_MGMT_WAPI_CERT) && +#endif !(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)) { if (debug_print) wpa_dbg(wpa_s, MSG_INFO, @@ -1339,12 +1397,35 @@ static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, " skip - non-OSEN network not allowed"); return false; } +#ifdef CONFIG_WAPI + if (((ssid->key_mgmt & WPA_KEY_MGMT_WAPI_PSK) || (ssid->key_mgmt & WPA_KEY_MGMT_WAPI_CERT)) && + (wapi_ie_len == 0)) { + wpa_dbg(wpa_s, MSG_DEBUG, " skip - non-WAPI network not allowed"); + return false; + } +#endif +#ifdef CONFIG_WAPI + if (wapi_ie_len > 0) { + if (!wpa && !wpa_supplicant_match_privacy(bss, ssid)) { + if (debug_print) + wpa_dbg(wpa_s, MSG_DEBUG, " skip - privacy mismatch"); + return false; + } + } else { + if (!wpa_supplicant_match_privacy(bss, ssid)) { + if (debug_print) + wpa_dbg(wpa_s, MSG_DEBUG, " skip - privacy mismatch"); + return false; + } + } +#else if (!wpa_supplicant_match_privacy(bss, ssid)) { if (debug_print) wpa_dbg(wpa_s, MSG_INFO, " skip - privacy mismatch"); return false; } +#endif if (ssid->mode != WPAS_MODE_MESH && !bss_is_ess(bss) && !bss_is_pbss(bss)) { @@ -2241,13 +2322,20 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, if (num > 10) num = 10; for (i = 0; i < num; i++) { +#ifdef CONFIG_WAPI + u8 buf[6]; +#else u8 buf[5]; +#endif struct wpa_scan_res *res = scan_res->res[i]; buf[0] = res->bssid[5]; buf[1] = res->qual & 0xff; buf[2] = res->noise & 0xff; buf[3] = res->level & 0xff; buf[4] = res->tsf & 0xff; +#ifdef CONFIG_WAPI + buf[5] = res->wapi_ie_len & 0xff; +#endif random_add_randomness(buf, sizeof(buf)); } #endif /* CONFIG_NO_RANDOM_POOL */ @@ -3451,6 +3539,61 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL); wpa_s->own_reconnect_req = 0; +#ifdef CONFIG_WAPI + if (wpa_s->current_ssid) { + wpa_printf(MSG_DEBUG, "[WAPI] wpa_s->current_ssid->wapi=%d.", wpa_s->current_ssid->wapi); + } else { + wpa_printf(MSG_DEBUG, "[WAPI] wpa_s->current_ssid not exist."); + } + + if ((wpa_s->current_ssid) && (wpa_s->current_ssid->wapi)) + { + wpa_printf(MSG_DEBUG, "[WAPI] associated to a wapi network."); + if (wpa_drv_get_bssid(wpa_s, bssid) >= 0 && + os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0) { + wpa_msg(wpa_s, MSG_DEBUG, "Associated to a new BSS: BSSID=" + MACSTR_SEC, MAC2STR_SEC(bssid)); + os_memcpy(wpa_s->bssid, bssid, ETH_ALEN); + os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); + wpa_supplicant_update_current_bss(wpa_s); + } + + wpa_hexdump(MSG_DEBUG, "bssid", bssid, sizeof(bssid)); + wpa_hexdump(MSG_DEBUG, "own mac", wpa_s->wapi_own_addr, ETH_ALEN); + + ft_completed = wpa_ft_is_completed(wpa_s->wpa); + if (wpa_s->ap_wapi_ie_len) { + wpa_printf(MSG_DEBUG, "wpa_s->ap_wapi_ie_len=%d", wpa_s->ap_wapi_ie_len); + wapi_asue_event(WAPI_EVENT_ASSOC, bssid, wpa_s->wapi_own_addr, wpa_s->ap_wapi_ie, + wpa_s->ap_wapi_ie_len); + } else { + wpa_printf(MSG_DEBUG, "ap_wapi_ie_len is Zero "); + wapi_asue_event(WAPI_EVENT_ASSOC, bssid, wpa_s->wapi_own_addr, NULL, 0); + } + + wpa_supplicant_cancel_auth_timeout(wpa_s); + wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED); + wpa_msg(wpa_s, MSG_INFO, "Associated with " MACSTR_SEC, MAC2STR_SEC(bssid)); + wpa_s->connection_set = 0; + if (data->assoc_info.req_ies && data->assoc_info.resp_ies) { + struct ieee802_11_elems req_elems, resp_elems; + if (ieee802_11_parse_elems(data->assoc_info.resp_ies, + data->assoc_info.resp_ies_len, + &resp_elems, 0) != ParseFailed && + ieee802_11_parse_elems(data->assoc_info.req_ies, + data->assoc_info.req_ies_len, + &req_elems, 0) != ParseFailed) { + wpa_s->connection_he = req_elems.he_capabilities && + resp_elems.he_capabilities; + wpa_s->connection_vht = req_elems.vht_capabilities && + resp_elems.vht_capabilities; + wpa_s->connection_ht = req_elems.ht_capabilities && + resp_elems.ht_capabilities; + wpa_s->connection_set = 1; + } + } + } else { +#endif ft_completed = wpa_ft_is_completed(wpa_s->wpa); if (data && wpa_supplicant_event_associnfo(wpa_s, data) < 0) @@ -3586,6 +3729,10 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, wpa_supplicant_req_auth_timeout(wpa_s, 10, 0); #endif } +#ifdef CONFIG_WAPI + } +#endif + wpa_supplicant_cancel_scan(wpa_s); if (ft_completed) { @@ -3799,6 +3946,42 @@ static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s, authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING; os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN); +#ifdef CONFIG_WAPI + wpa_printf(MSG_DEBUG, "wpa_s->ap_wapi_ie_len=%d\twpa_s->assoc_wapi_ie_len =%d\n", + wpa_s->ap_wapi_ie_len, wpa_s->assoc_wapi_ie_len); + if ((wpa_s->ap_wapi_ie_len > 0) && (wpa_s->assoc_wapi_ie_len > 0)) { + wapi_asue_event(WAPI_EVENT_DISASSOC, wpa_s->bssid, wpa_s->wapi_own_addr, NULL, 0); + if (wpa_s->wpa_state >= WPA_ASSOCIATED) + wpa_supplicant_req_scan(wpa_s, 0, 100000); + bssid = wpa_s->bssid; + if (os_memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0) + bssid = wpa_s->pending_bssid; + wpa_bssid_ignore_add(wpa_s, bssid); + + if (locally_generated) + wpa_s->disconnect_reason = -reason_code; + else + wpa_s->disconnect_reason = reason_code; + + wpas_notify_disconnect_reason(wpa_s); + + wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "- Disconnect event - " + "remove keys"); + wpa_supplicant_mark_disassoc(wpa_s); + + wpa_s->ap_wapi_ie_len = 0; + wpa_s->assoc_wapi_ie_len = 0; + os_memset(wpa_s->ap_wapi_ie, 0, sizeof(wpa_s->ap_wapi_ie)); + os_memset(wpa_s->assoc_wapi_ie, 0, sizeof(wpa_s->assoc_wapi_ie)); + + if (wpa_s->wapi_conf != NULL) { + wapi_config_free(wpa_s->wapi_conf); + wpa_s->wapi_conf = NULL; + } + wpas_connect_work_done(wpa_s); + } else { +#endif + if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { /* * At least Host AP driver and a Prism3 card seemed to be @@ -3936,6 +4119,9 @@ skip_rewrite_reason: */ wpa_supplicant_req_scan(wpa_s, 0, 100000); } +#ifdef CONFIG_WAPI + } +#endif } @@ -3962,6 +4148,9 @@ wpa_supplicant_event_michael_mic_failure(struct wpa_supplicant *wpa_s, struct os_reltime t; wpa_msg(wpa_s, MSG_WARNING, "Michael MIC failure detected"); +#ifdef CONFIG_WAPI + if (!(wpa_s->current_ssid && wpa_s->current_ssid->wapi)) { +#endif pairwise = (data && data->michael_mic_failure.unicast); os_get_reltime(&t); if ((wpa_s->last_michael_mic_error.sec && @@ -4044,6 +4233,9 @@ wpa_supplicant_event_michael_mic_failure(struct wpa_supplicant *wpa_s, #endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */ } wpa_s->last_michael_mic_error = t; +#ifdef CONFIG_WAPI + } +#endif wpa_s->mic_errors_seen++; } @@ -4123,6 +4315,11 @@ wpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s, } #endif /* CONFIG_MATCH_IFACE */ +#ifdef CONFIG_WAPI + l2_packet_deinit(wpa_s->l2_wapi); + wpa_s->l2_wapi = NULL; +#endif + #ifdef CONFIG_TERMINATE_ONLASTIF /* check if last interface */ if (!any_interfaces(wpa_s->global->ifaces)) diff --git a/wpa_supplicant-2.9_standard/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant-2.9_standard/wpa_supplicant/wpa_supplicant.c index 0be2d79..569707b 100644 --- a/wpa_supplicant-2.9_standard/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant-2.9_standard/wpa_supplicant/wpa_supplicant.c @@ -63,6 +63,10 @@ #include "wnm_sta.h" #include "wpas_kay.h" #include "mesh.h" +#ifdef CONFIG_WAPI +#include "wapi_asue_i.h" +#include "securec.h" +#endif #include "dpp_supplicant.h" #ifdef CONFIG_MESH #include "ap/ap_config.h" @@ -548,6 +552,10 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) eapol_sm_register_scard_ctx(wpa_s->eapol, NULL); l2_packet_deinit(wpa_s->l2); wpa_s->l2 = NULL; +#ifdef CONFIG_WAPI + l2_packet_deinit(wpa_s->l2_wapi); + wpa_s->l2_wapi = NULL; +#endif if (wpa_s->l2_br) { l2_packet_deinit(wpa_s->l2_br); wpa_s->l2_br = NULL; @@ -1506,6 +1514,8 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, proto = WPA_PROTO_OSEN; else if (ssid->proto & WPA_PROTO_RSN) proto = WPA_PROTO_RSN; + else if (ssid->proto & WPA_PROTO_WAPI) + proto = WPA_PROTO_WAPI; else proto = WPA_PROTO_WPA; if (wpa_supplicant_suites_from_ai(wpa_s, ssid, &ie) < 0) { @@ -1709,6 +1719,14 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, } else if (sel & WPA_KEY_MGMT_WPA_NONE) { wpa_s->key_mgmt = WPA_KEY_MGMT_WPA_NONE; wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-NONE"); +#ifdef CONFIG_WAPI + } else if (sel & WPA_KEY_MGMT_WAPI_PSK) { + wpa_s->key_mgmt = WPA_KEY_MGMT_WAPI_PSK; + wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WAPI-PSK"); + } else if (sel & WPA_KEY_MGMT_WAPI_CERT) { + wpa_s->key_mgmt = WPA_KEY_MGMT_WAPI_CERT; + wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WAPI-CERT"); +#endif #ifdef CONFIG_HS20 } else if (sel & WPA_KEY_MGMT_OSEN) { wpa_s->key_mgmt = WPA_KEY_MGMT_OSEN; @@ -3674,6 +3692,86 @@ void wpas_update_mbo_connect_params(struct wpa_supplicant *wpa_s) #endif /* CONFIG_MBO */ +#ifdef CONFIG_WAPI +struct wapi_config* wapi_config_init(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) +{ + struct wapi_config *config = NULL; + CNTAP_PARA lib_param; + config = os_malloc(sizeof(*config)); + if (config == NULL) { + wpa_printf(MSG_ERROR, "wapi config is NULL"); + return NULL; + } + os_memset(config, 0, sizeof(*config)); + config->wapi_policy = ssid->wapi; + wpa_printf(MSG_DEBUG, "wapi_policy '%d'", config->wapi_policy); + + config->ssid_len = ssid->ssid_len; + config->ssid = (u8 *)strdup((const char *)ssid->ssid); + if (config->wapi_policy == WAPI_TYPE_CERT) { + lib_param.authType = AUTH_TYPE_WAPI_CERT; + lib_param.wapi_cert_sel_mode = DEFAULT_WAPI_USER_CERT_MODE; + if (strcpy_s(lib_param.wapi_cert_sel, sizeof(lib_param.wapi_cert_sel), ssid->wapi_user_sel_cert) != 0 || + strcpy_s(lib_param.wapi_ca_cert, sizeof(lib_param.wapi_ca_cert), ssid->wapi_ca_cert) != 0) { + wpa_printf(MSG_ERROR, "wapi cert copy is error!"); + wapi_config_free(config); + return NULL; + } + } else if (config->wapi_policy == WAPI_TYPE_PSK) { + lib_param.authType = AUTH_TYPE_WAPI_PSK; + if (ssid->wapi_psk == NULL) { + wpa_printf(MSG_ERROR, "wapi_psk is null"); + wapi_config_free(config); + return NULL; + } + wpa_printf(MSG_DEBUG, "psk_key_type = %d", ssid->psk_key_type); + if (ssid->psk_key_type == KEY_TYPE_HEX) { + lib_param.kt = KEY_TYPE_HEX; + lib_param.kl = os_strlen(ssid->wapi_psk); + os_memcpy(lib_param.kv, ssid->wapi_psk, lib_param.kl); + } else { + lib_param.kt = KEY_TYPE_ASCII; + lib_param.kl = os_strlen(ssid->wapi_psk); + os_memcpy(lib_param.kv, ssid->wapi_psk, lib_param.kl); + } + } else { + wpa_printf(MSG_ERROR, "wapi_policy is not match!"); + wapi_config_free(config); + return NULL; + } + config->group_cipher = WPA_CIPHER_SMS4; + config->pairwise_cipher = WPA_CIPHER_SMS4; + if (wapi_asue_set_config(&lib_param) != 0) { + wpa_printf(MSG_ERROR, "wapi_asue_set_config failed"); + if (config->wapi_policy == WAPI_TYPE_CERT) { + wpa_msg(wpa_s, MSG_INFO, "WAPI: certificate initialization failed"); + } + wapi_config_free(config); + return NULL; + } + + return config; +} + +void wapi_config_free(struct wapi_config *config) +{ + struct wapi_config *prev = NULL; + prev = config; + if (prev) { + if (prev->ssid) { + free(prev->ssid); + prev->ssid = NULL; + } + if (prev->cert_name) { + free(prev->cert_name); + prev->cert_name = NULL; + } + free(config); + config = NULL; + } +} +#endif + static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) { struct wpa_connect_work *cwork = work->ctx; @@ -3797,6 +3895,73 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) wpa_supplicant_cancel_sched_scan(wpa_s); wpa_supplicant_cancel_scan(wpa_s); +#ifdef CONFIG_WAPI + if ((ssid->key_mgmt == WPA_KEY_MGMT_WAPI_PSK) || + (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_CERT)) { + wpa_printf(MSG_DEBUG, "Associating to a WAPI network: wapi %d proto %d key_mgmt %d", + ssid->wapi, ssid->proto, ssid->key_mgmt); + if (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_CERT) { + ssid->wapi = WAPI_TYPE_CERT; + } else if (ssid->key_mgmt == WPA_KEY_MGMT_WAPI_PSK) { + ssid->wapi = WAPI_TYPE_PSK; + } else { + wpa_printf(MSG_ERROR, "Can't assoc: key_mgmt is missing for current wapi ssid"); + wpas_connect_work_done(wpa_s); + wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); + return; + } + wpa_s->key_mgmt = ssid->key_mgmt; + wapi_asue_update_iface(wpa_s); + wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING); + + wpa_s->wapi_conf = wapi_config_init(wpa_s, ssid); + if (wpa_s->wapi_conf == NULL) { + wpa_printf(MSG_ERROR, "Can't assoc: initialize wapi_conf failed"); + wpas_connect_work_done(wpa_s); + wpas_notify_assoc_status_code(wpa_s); + wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); + return; + } + + params.pairwise_suite = wpa_s->wapi_conf->pairwise_cipher; + params.group_suite = wpa_s->wapi_conf->group_cipher; + params.key_mgmt_suite = ssid->key_mgmt; + params.ssid = ssid->ssid; + params.ssid_len = ssid->ssid_len; + params.mode = ssid->mode; + params.wpa_ie_len = wpa_s->assoc_wapi_ie_len; + params.wpa_ie = wpa_s->assoc_wapi_ie; + + if (bss) { + params.bssid = bss->bssid; + params.freq.freq = bss->freq ; + + wpa_s->ap_wapi_ie_len = bss->wapi_ie_len; + if (bss->wapi_ie_len) { + memcpy_s(wpa_s->ap_wapi_ie, sizeof(wpa_s->ap_wapi_ie), + wpa_bss_get_ie((const struct wpa_bss *)bss, WLAN_EID_WAPI), + bss->wapi_ie_len); + wpa_hexdump(MSG_DEBUG, "wpa_s->ap_wapi_ie", wpa_s->ap_wapi_ie, wpa_s->ap_wapi_ie_len); + } + } + + if (ssid->mode == 1 && ssid->frequency > 0 && params.freq.freq == 0) { + params.freq.freq = ssid->frequency; + } + + if (!memcmp(wpa_s->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN)) { + int timeout = 20; + wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0); + wpa_hexdump(MSG_DEBUG, "[WAPI] wpa_drv_associate: params->wpa_ie", params.wpa_ie, params.wpa_ie_len); + ret = wpa_drv_associate(wpa_s, ¶ms); + if (ret < 0) { + wpa_printf(MSG_ERROR, "wapi_drv_associate() failed\n"); + wpas_connect_work_done(wpa_s); + wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); + } + } + } else { +#endif wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL); use_crypt = 1; @@ -3838,7 +4003,14 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) wpa_supplicant_set_wpa_none_key(wpa_s, ssid); } +#ifdef CONFIG_WAPI + if ((ssid->key_mgmt != WPA_KEY_MGMT_WAPI_PSK) || + (ssid->key_mgmt != WPA_KEY_MGMT_WAPI_CERT)) { + wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING); + } +#else wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING); +#endif if (bss) { params.ssid = bss->ssid; params.ssid_len = bss->ssid_len; @@ -4148,6 +4320,9 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) */ eapol_sm_invalidate_cached_session(wpa_s->eapol); } +#ifdef CONFIG_WAPI + } +#endif old_ssid = wpa_s->current_ssid; wpa_s->current_ssid = ssid; @@ -4157,9 +4332,15 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) hs20_configure_frame_filters(wpa_s); #endif /* CONFIG_HS20 */ } +#ifdef CONFIG_WAPI + if (ssid->wapi == WAPI_TYPE_NONE) { +#endif wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid); wpa_supplicant_initiate_eapol(wpa_s); +#ifdef CONFIG_WAPI + } +#endif if (old_ssid != wpa_s->current_ssid) wpas_notify_network_changed(wpa_s); } @@ -5248,6 +5429,11 @@ int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s) !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) && !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) { l2_packet_deinit(wpa_s->l2); +#ifdef CONFIG_WAPI + wpa_s->l2_wapi = l2_packet_init(wpa_s->ifname, wpa_drv_get_mac_addr(wpa_s), + ETH_P_WAI, wapi_asue_rx_wai, wpa_s, 0); + wpa_printf(MSG_DEBUG, "wpa_s->l2_wapi = %p ", wpa_s->l2_wapi); +#endif #ifdef CONFIG_VENDOR_EXT wpa_s->l2 = l2_packet_init(wpa_vendor_ext_get_drv_ifname(wpa_s), #else @@ -5258,6 +5444,12 @@ int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s) wpas_eapol_needs_l2_packet(wpa_s) ? wpa_supplicant_rx_eapol : NULL, wpa_s, 0); +#ifdef CONFIG_WAPI + if (wpa_s->l2_wapi == NULL) { + wpa_printf(MSG_ERROR, "wpa_s->l2_wapi is NULL!"); + return -1; + } +#endif if (wpa_s->l2 == NULL) return -1; @@ -5290,6 +5482,12 @@ int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s) if (wpa_s->fst) fst_update_mac_addr(wpa_s->fst, wpa_s->own_addr); #endif /* CONFIG_FST */ +#ifdef CONFIG_WAPI + if (wpa_s->l2_wapi && l2_packet_get_own_addr(wpa_s->l2_wapi, wpa_s->wapi_own_addr)) { + wpa_printf(MSG_ERROR, "Failed to get own WAPI L2 address"); + return -1; + } +#endif return 0; } @@ -5494,6 +5692,11 @@ static struct wpa_supplicant *wpa_supplicant_alloc(struct wpa_supplicant *parent } #endif +#ifdef CONFIG_WAPI + wpa_s->ap_wapi_ie_len = 0; + wpa_s->assoc_wapi_ie_len = 0; +#endif + dl_list_init(&wpa_s->bss_tmp_disallowed); dl_list_init(&wpa_s->fils_hlp_req); #ifdef CONFIG_TESTING_OPTIONS @@ -7635,6 +7838,12 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params) wpas_periodic, global, NULL); #ifdef CONFIG_P2P_160M global_op_class = global_op_class_for_dfs; +#endif +#ifdef CONFIG_WAPI + if (wapi_asue_init()) { + wpa_printf(MSG_ERROR, "wapi: wapi_asue_init fail"); + return NULL; + } #endif return global; } @@ -7698,6 +7907,9 @@ void wpa_supplicant_deinit(struct wpa_global *global) #ifdef CONFIG_WIFI_DISPLAY wifi_display_deinit(global); #endif /* CONFIG_WIFI_DISPLAY */ +#ifdef CONFIG_WAPI + wapi_asue_deinit(); +#endif while (global->ifaces) wpa_supplicant_remove_iface(global, global->ifaces, 1); diff --git a/wpa_supplicant-2.9_standard/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant-2.9_standard/wpa_supplicant/wpa_supplicant_i.h index 43af14f..7480b49 100644 --- a/wpa_supplicant-2.9_standard/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant-2.9_standard/wpa_supplicant/wpa_supplicant_i.h @@ -703,12 +703,18 @@ struct wpa_supplicant { struct wpa_supplicant *p2pdev; struct wpa_supplicant *next; struct l2_packet_data *l2; +#ifdef CONFIG_WAPI + struct l2_packet_data *l2_wapi; +#endif /* WAPI */ struct l2_packet_data *l2_br; struct os_reltime roam_start; struct os_reltime roam_time; struct os_reltime session_start; struct os_reltime session_length; unsigned char own_addr[ETH_ALEN]; +#ifdef CONFIG_WAPI + unsigned char wapi_own_addr[ETH_ALEN]; +#endif /* WAPI */ unsigned char perm_addr[ETH_ALEN]; char ifname[100]; #ifdef CONFIG_MATCH_IFACE @@ -902,6 +908,13 @@ struct wpa_supplicant { * pending vendor scan request. */ u64 curr_scan_cookie; +#ifdef CONFIG_WAPI + struct wapi_config *wapi_conf; + u8 assoc_wapi_ie[256]; + u8 assoc_wapi_ie_len; + u8 ap_wapi_ie[256]; + u8 ap_wapi_ie_len; +#endif #define MAX_SCAN_ID 16 int scan_id[MAX_SCAN_ID]; unsigned int scan_id_count; diff --git a/wpa_supplicant-2.9_standard/wpa_vendor_ext.gni b/wpa_supplicant-2.9_standard/wpa_vendor_ext.gni index 0e5857f..54b5c52 100644 --- a/wpa_supplicant-2.9_standard/wpa_vendor_ext.gni +++ b/wpa_supplicant-2.9_standard/wpa_vendor_ext.gni @@ -19,4 +19,11 @@ if (wpa_supplicant_vendor_ext && wpa_vendor_gni != "") { import("${wpa_vendor_gni}") ext_cflags += [ "-DCONFIG_VENDOR_EXT" ] + + if (wpa_supplicant_wapi) { + ext_cflags += [ + "-DCONFIG_WAPI", + "-DLE", + ] + } } -- Gitee