From 497c8b09223eb232c8891ab3447c695263e939db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Sat, 20 May 2023 21:19:56 +0000 Subject: [PATCH] wifi: provide WPA3-personal support This commit introduces preliminary support for joining networks secured via WPA3-personal. So far it was only tested with the one OpenWRT AP configured for WPA3 (see excerpt below) where it WPA3-only as well as WPA2/WPA3 mixed worked fine. Scan results excerpt: 00:11:22:33:44:55 5180 -45 [WPA2-SAE-CCMP][SAE-H2E][ESS][UTF-8] PewPew 00:11:22:33:44:55 2412 -67 [WPA2-PSK+SAE+PSK-SHA256-CCMP][SAE-H2E][ESS][UTF-8] PewPew2 Issue #4861. --- repos/dde_linux/lib/mk/wpa_supplicant.mk | 7 ++- repos/dde_linux/src/drivers/wifi/README | 11 ++-- repos/dde_linux/src/drivers/wifi/frontend.h | 70 ++++++++++++++++++--- repos/pc/run/pc_wifi.run | 13 +++- 4 files changed, 83 insertions(+), 18 deletions(-) diff --git a/repos/dde_linux/lib/mk/wpa_supplicant.mk b/repos/dde_linux/lib/mk/wpa_supplicant.mk index eef1413562..3fe6593f26 100644 --- a/repos/dde_linux/lib/mk/wpa_supplicant.mk +++ b/repos/dde_linux/lib/mk/wpa_supplicant.mk @@ -44,7 +44,8 @@ INC_DIR += $(WS_CONTRIB_DIR)/wpa_supplicant CC_OPT += -DCONFIG_BACKEND_FILE -DCONFIG_NO_CONFIG_WRITE \ -DCONFIG_SME -DCONFIG_CTRL_IFACE \ -DCONFIG_BGSCAN -DCONFIG_BGSCAN_SIMPLE \ - -DCONFIG_OPENSSL_CMAC -DCONFIG_SHA256 + -DCONFIG_OPENSSL_CMAC -DCONFIG_SHA256 \ + -DCONFIG_SAE -DCONFIG_ECC CC_OPT += -DTLS_DEFAULT_CIPHERS=\"DEFAULT:!EXP:!LOW\" @@ -52,17 +53,19 @@ INC_DIR += $(WS_CONTRIB_DIR)/src/ # common SRC_C_common = ieee802_11_common.c wpa_common.c hw_features_common.c \ - ctrl_iface_common.c + ctrl_iface_common.c sae.c dragonfly.c SRC_C += $(addprefix src/common/, $(SRC_C_common)) INC_DIR += $(WS_CONTRIB_DIR)/src/common # crypto SRC_C_crypto = crypto_openssl.c \ + dh_groups.c \ ms_funcs.c \ random.c \ sha1-prf.c \ sha1-tlsprf.c \ sha256-prf.c \ + sha256-kdf.c \ tls_openssl.c SRC_C += $(addprefix src/crypto/, $(SRC_C_crypto)) INC_DIR += $(WS_CONTRIB_DIR)/src/crypto diff --git a/repos/dde_linux/src/drivers/wifi/README b/repos/dde_linux/src/drivers/wifi/README index f1f9503b84..e583824999 100644 --- a/repos/dde_linux/src/drivers/wifi/README +++ b/repos/dde_linux/src/drivers/wifi/README @@ -89,8 +89,9 @@ connect to a network: To temporarily prevent any radio activity, the 'rfkill' attribute can be set to 'true'. -If the network is protected by, e.g., WPA/WPA2, the protection type, either -'WPA' or 'WPA2' as well as the the passphrase have to be specified. +If the network is protected by, e.g., WPA/WPA2/WPA3, the protection type, +either 'WPA', 'WPA2' or 'WPA3' as well as the the passphrase have to be +specified. The 'bssid' attribute can be used to select a specifc accesspoint within a network. Of all attributes only the 'ssid' attribute is mandatory, all others are optional and should only be used when needed. @@ -150,9 +151,9 @@ the 'rfkill' attribute. By subscribing to both reports and providing the required 'wifi_config' ROM module, a component is able control the wireless driver. -Currently only WPA/WPA2 protection using a passphrase is supported and the the -SSID is copied verbatim. At the moment, there is no way to express or escape -non alphanumeric characters. +Currently only WPA/WPA2/WPA3 protection using a passphrase is supported and +the SSID is copied verbatim. At the moment, there is no way to express or +escape non alphanumeric characters. The driver optionally reports the following information under the label "devices" if requested in the config as depicted. diff --git a/repos/dde_linux/src/drivers/wifi/frontend.h b/repos/dde_linux/src/drivers/wifi/frontend.h index 6460516adf..d296e01124 100644 --- a/repos/dde_linux/src/drivers/wifi/frontend.h +++ b/repos/dde_linux/src/drivers/wifi/frontend.h @@ -185,6 +185,7 @@ struct Accesspoint : Genode::Interface bool valid() const { return ssid.length() > 1; } bool bssid_valid() const { return bssid.length() > 1; } bool wpa() const { return prot != "NONE"; } + bool wpa3() const { return prot == "WPA3"; } bool stored() const { return id != -1; } }; @@ -233,11 +234,13 @@ static void for_each_result_line(char const *msg, FUNC const &func) bool const is_wpa1 = Util::string_contains((char const*)s[3], "WPA"); bool const is_wpa2 = Util::string_contains((char const*)s[3], "WPA2"); + bool const is_wpa3 = Util::string_contains((char const*)s[3], "SAE"); unsigned signal = Util::approximate_quality(s[2]); char const *prot = is_wpa1 ? "WPA" : "NONE"; prot = is_wpa2 ? "WPA2" : prot; + prot = is_wpa3 ? "WPA3" : prot; Accesspoint ap(s[0], s[1], prot, s[4], signal); @@ -556,14 +559,16 @@ struct Wifi::Frontend : Wifi::Rfkill_notification_handler INITIATE_SCAN = 0x00|SCAN, PENDING_RESULTS = 0x10|SCAN, - ADD_NETWORK = 0x00|NETWORK, - FILL_NETWORK_SSID = 0x10|NETWORK, - FILL_NETWORK_BSSID = 0x20|NETWORK, - FILL_NETWORK_PSK = 0x30|NETWORK, - REMOVE_NETWORK = 0x40|NETWORK, - ENABLE_NETWORK = 0x50|NETWORK, - DISABLE_NETWORK = 0x60|NETWORK, - LIST_NETWORKS = 0x80|NETWORK, + ADD_NETWORK = 0x00|NETWORK, + FILL_NETWORK_SSID = 0x10|NETWORK, + FILL_NETWORK_BSSID = 0x20|NETWORK, + FILL_NETWORK_KEY_MGMT = 0x30|NETWORK, + FILL_NETWORK_PSK = 0x40|NETWORK, + REMOVE_NETWORK = 0x50|NETWORK, + ENABLE_NETWORK = 0x60|NETWORK, + DISABLE_NETWORK = 0x70|NETWORK, + LIST_NETWORKS = 0x90|NETWORK, + SET_NETWORK_PMF = 0xA0|NETWORK, CONNECTING = 0x00|CONNECT, CONNECTED = 0x10|CONNECT, @@ -581,6 +586,7 @@ struct Wifi::Frontend : Wifi::Rfkill_notification_handler case ADD_NETWORK: return "add network"; case FILL_NETWORK_SSID: return "fill network ssid"; case FILL_NETWORK_BSSID: return "fill network bssid"; + case FILL_NETWORK_KEY_MGMT: return "fill network key_mgmt"; case FILL_NETWORK_PSK: return "fill network pass"; case REMOVE_NETWORK: return "remove network"; case ENABLE_NETWORK: return "enable network"; @@ -591,6 +597,7 @@ struct Wifi::Frontend : Wifi::Rfkill_notification_handler case STATUS: return "status"; case LIST_NETWORKS: return "list networks"; case INFO: return "info"; + case SET_NETWORK_PMF: return "set network pmf"; default: return "unknown"; }; } @@ -922,6 +929,18 @@ struct Wifi::Frontend : Wifi::Rfkill_notification_handler " bssid ", bssid)); } + void _network_set_key_mgmt_sae() + { + _submit_cmd(Cmd_str("SET_NETWORK ", _processed_ap->id, + " key_mgmt SAE")); + } + + void _network_set_pmf() + { + _submit_cmd(Cmd_str("SET_NETWORK ", _processed_ap->id, + " ieee80211w 2")); + } + void _network_set_psk() { if (_processed_ap->wpa()) { @@ -1018,6 +1037,41 @@ struct Wifi::Frontend : Wifi::Rfkill_notification_handler _state_transition(_state, State::IDLE); } else { + /* + * For the moment branch here to handle WPA3-personal-only + * explicitly. + */ + if (_processed_ap->wpa3()) { + _state_transition(_state, State::FILL_NETWORK_KEY_MGMT); + _network_set_key_mgmt_sae(); + } else { + _state_transition(_state, State::FILL_NETWORK_PSK); + _network_set_psk(); + } + + successfully = true; + } + break; + case State::FILL_NETWORK_KEY_MGMT: + _state_transition(_state, State::IDLE); + + if (!cmd_successful(msg)) { + Genode::error("could not set key_mgmt for network: ", msg); + _state_transition(_state, State::IDLE); + } else { + _state_transition(_state, State::SET_NETWORK_PMF); + _network_set_pmf(); + + successfully = true; + } + break; + case State::SET_NETWORK_PMF: + _state_transition(_state, State::IDLE); + + if (!cmd_successful(msg)) { + Genode::error("could not set PMF for network: ", msg); + _state_transition(_state, State::IDLE); + } else { _state_transition(_state, State::FILL_NETWORK_PSK); _network_set_psk(); diff --git a/repos/pc/run/pc_wifi.run b/repos/pc/run/pc_wifi.run index 92b9af7dde..f27498c8c5 100644 --- a/repos/pc/run/pc_wifi.run +++ b/repos/pc/run/pc_wifi.run @@ -17,6 +17,13 @@ proc wifi_psk { } { return $::env(GENODE_WIFI_PSK) } +proc wifi_wpa { } { + if {![info exists ::env(GENODE_WIFI_WPA)]} { + return WPA2 + } + return $::env(GENODE_WIFI_WPA) +} + # # widi_drv config generator (supporting a network list) # @@ -232,15 +239,15 @@ append config { -} [wifi_config 30 5 no [list "[wifi_ssid] WPA2 [wifi_psk] yes"]] { +} [wifi_config 30 5 no [list "[wifi_ssid] [wifi_wpa] [wifi_psk] yes"]] { -} [wifi_config 30 5 yes [list "[wifi_ssid] WPA2 [wifi_psk] yes"]] { +} [wifi_config 30 5 yes [list "[wifi_ssid] [wifi_wpa] [wifi_psk] yes"]] { -} [wifi_config 30 5 no [list "[wifi_ssid] WPA2 [wifi_psk] yes"]] { +} [wifi_config 30 5 no [list "[wifi_ssid] [wifi_wpa] [wifi_psk] yes"]] {