* [PATCH v2 1/3] netdev: factor out scan_bss from CMD_CONNECT builder
@ 2021-09-03 19:26 James Prestwood
2021-09-03 19:26 ` [PATCH v2 2/3] wsc: set ssid in handshake James Prestwood
2021-09-03 19:26 ` [PATCH v2 3/3] owe: netdev: refactor to remove OWE as an auth-proto James Prestwood
0 siblings, 2 replies; 3+ messages in thread
From: James Prestwood @ 2021-09-03 19:26 UTC (permalink / raw)
To: iwd
[-- Attachment #1: Type: text/plain, Size: 3767 bytes --]
In order to support OWE in the CMD_CONNECT path the scan_bss parameter
needs to be removed since this is lost after netdev_connect returns.
Nearly everything needed is also stored in the handshake except the
privacy capability which is now being mirrored in the netdev object
itself.
---
src/netdev.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/src/netdev.c b/src/netdev.c
index a5d1b8ed..8592685c 100644
--- a/src/netdev.c
+++ b/src/netdev.c
@@ -181,6 +181,7 @@ struct netdev {
bool events_ready : 1;
bool retry_auth : 1;
bool in_reassoc : 1;
+ bool privacy : 1;
};
struct netdev_preauth_state {
@@ -788,6 +789,7 @@ static void netdev_connect_free(struct netdev *netdev)
netdev->ignore_connect_event = false;
netdev->expect_connect_failure = false;
netdev->cur_rssi_low = false;
+ netdev->privacy = false;
if (netdev->connect_cmd) {
l_genl_msg_unref(netdev->connect_cmd);
@@ -2901,7 +2903,6 @@ static void netdev_fils_tx_associate(struct iovec *fils_iov, size_t n_fils_iov,
}
static struct l_genl_msg *netdev_build_cmd_connect(struct netdev *netdev,
- struct scan_bss *bss,
struct handshake_state *hs,
const uint8_t *prev_bssid,
const struct iovec *vendor_ies,
@@ -2924,10 +2925,9 @@ static struct l_genl_msg *netdev_build_cmd_connect(struct netdev *netdev,
msg = l_genl_msg_new_sized(NL80211_CMD_CONNECT, 512);
l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &netdev->index);
l_genl_msg_append_attr(msg, NL80211_ATTR_WIPHY_FREQ,
- 4, &bss->frequency);
- l_genl_msg_append_attr(msg, NL80211_ATTR_MAC, ETH_ALEN, bss->addr);
- l_genl_msg_append_attr(msg, NL80211_ATTR_SSID,
- bss->ssid_len, bss->ssid);
+ 4, &netdev->frequency);
+ l_genl_msg_append_attr(msg, NL80211_ATTR_MAC, ETH_ALEN, hs->aa);
+ l_genl_msg_append_attr(msg, NL80211_ATTR_SSID, hs->ssid_len, hs->ssid);
l_genl_msg_append_attr(msg, NL80211_ATTR_AUTH_TYPE, 4, &auth_type);
switch (nhs->type) {
@@ -2950,7 +2950,7 @@ static struct l_genl_msg *netdev_build_cmd_connect(struct netdev *netdev,
l_genl_msg_append_attr(msg, NL80211_ATTR_PREV_BSSID, ETH_ALEN,
prev_bssid);
- if (bss->capability & IE_BSS_CAP_PRIVACY)
+ if (netdev->privacy)
l_genl_msg_append_attr(msg, NL80211_ATTR_PRIVACY, 0, NULL);
l_genl_msg_append_attr(msg, NL80211_ATTR_SOCKET_OWNER, 0, NULL);
@@ -3476,6 +3476,10 @@ static void netdev_connect_common(struct netdev *netdev,
bool is_rsn = hs->supplicant_ie != NULL;
const uint8_t *prev_bssid = prev_bss ? prev_bss->addr : NULL;
+ netdev->frequency = bss->frequency;
+ netdev->privacy = bss->capability & IE_BSS_CAP_PRIVACY;
+ handshake_state_set_authenticator_address(hs, bss->addr);
+
if (!is_rsn)
goto build_cmd_connect;
@@ -3519,8 +3523,8 @@ static void netdev_connect_common(struct netdev *netdev,
break;
default:
build_cmd_connect:
- cmd_connect = netdev_build_cmd_connect(netdev, bss, hs,
- prev_bssid, vendor_ies, num_vendor_ies);
+ cmd_connect = netdev_build_cmd_connect(netdev, hs, prev_bssid,
+ vendor_ies, num_vendor_ies);
if (!is_offload(hs) && (is_rsn || hs->settings_8021x)) {
sm = eapol_sm_new(hs);
@@ -3536,13 +3540,10 @@ build_cmd_connect:
netdev->user_data = user_data;
netdev->handshake = hs;
netdev->sm = sm;
- netdev->frequency = bss->frequency;
netdev->cur_rssi = bss->signal_strength / 100;
netdev_rssi_level_init(netdev);
netdev_cqm_rssi_update(netdev);
- handshake_state_set_authenticator_address(hs, bss->addr);
-
if (!wiphy_has_ext_feature(netdev->wiphy,
NL80211_EXT_FEATURE_CAN_REPLACE_PTK0))
handshake_state_set_no_rekey(hs, true);
--
2.31.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v2 2/3] wsc: set ssid in handshake
2021-09-03 19:26 [PATCH v2 1/3] netdev: factor out scan_bss from CMD_CONNECT builder James Prestwood
@ 2021-09-03 19:26 ` James Prestwood
2021-09-03 19:26 ` [PATCH v2 3/3] owe: netdev: refactor to remove OWE as an auth-proto James Prestwood
1 sibling, 0 replies; 3+ messages in thread
From: James Prestwood @ 2021-09-03 19:26 UTC (permalink / raw)
To: iwd
[-- Attachment #1: Type: text/plain, Size: 694 bytes --]
netdev now assumes the SSID was set in the handshake (normally via
network_handshake_setup) but WSC calls netdev_connect directly so
it also should set the SSID.
---
src/wsc.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/wsc.c b/src/wsc.c
index 4ab497d4..2618497a 100644
--- a/src/wsc.c
+++ b/src/wsc.c
@@ -356,6 +356,7 @@ static int wsc_enrollee_connect(struct wsc_enrollee *wsce, struct scan_bss *bss,
handshake_state_set_event_func(hs, wsc_enrollee_handshake_event, wsce);
handshake_state_set_8021x_config(hs, settings);
+ handshake_state_set_ssid(hs, bss->ssid, bss->ssid_len);
wsce->eap_settings = settings;
request.version2 = true;
--
2.31.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v2 3/3] owe: netdev: refactor to remove OWE as an auth-proto
2021-09-03 19:26 [PATCH v2 1/3] netdev: factor out scan_bss from CMD_CONNECT builder James Prestwood
2021-09-03 19:26 ` [PATCH v2 2/3] wsc: set ssid in handshake James Prestwood
@ 2021-09-03 19:26 ` James Prestwood
1 sibling, 0 replies; 3+ messages in thread
From: James Prestwood @ 2021-09-03 19:26 UTC (permalink / raw)
To: iwd
[-- Attachment #1: Type: text/plain, Size: 26863 bytes --]
---
src/netdev.c | 545 +++++++++++++++++++++++++++------------------------
src/netdev.h | 1 +
src/owe.c | 148 ++------------
src/owe.h | 12 +-
4 files changed, 313 insertions(+), 393 deletions(-)
v2:
* Move OWE AKM case after the potential to go to psk_offload.
* use existing eapol_sm_new rather than creating the SM later
diff --git a/src/netdev.c b/src/netdev.c
index 8592685c..3aa373c5 100644
--- a/src/netdev.c
+++ b/src/netdev.c
@@ -119,6 +119,7 @@ struct netdev {
void *user_data;
struct eapol_sm *sm;
struct auth_proto *ap;
+ struct owe_sm *owe_sm;
struct handshake_state *handshake;
uint32_t connect_cmd_id;
uint32_t disconnect_cmd_id;
@@ -752,6 +753,11 @@ static void netdev_connect_free(struct netdev *netdev)
netdev->ap = NULL;
}
+ if (netdev->owe_sm) {
+ owe_sm_free(netdev->owe_sm);
+ netdev->owe_sm = NULL;
+ }
+
eapol_preauth_cancel(netdev->index);
if (netdev->handshake) {
@@ -2094,6 +2100,228 @@ static void netdev_driver_connected(struct netdev *netdev)
eapol_register(netdev->sm);
}
+static unsigned int ie_rsn_akm_suite_to_nl80211(enum ie_rsn_akm_suite akm)
+{
+ switch (akm) {
+ case IE_RSN_AKM_SUITE_8021X:
+ return CRYPTO_AKM_8021X;
+ case IE_RSN_AKM_SUITE_PSK:
+ return CRYPTO_AKM_PSK;
+ case IE_RSN_AKM_SUITE_FT_OVER_8021X:
+ return CRYPTO_AKM_FT_OVER_8021X;
+ case IE_RSN_AKM_SUITE_FT_USING_PSK:
+ return CRYPTO_AKM_FT_USING_PSK;
+ case IE_RSN_AKM_SUITE_8021X_SHA256:
+ return CRYPTO_AKM_8021X_SHA256;
+ case IE_RSN_AKM_SUITE_PSK_SHA256:
+ return CRYPTO_AKM_PSK_SHA256;
+ case IE_RSN_AKM_SUITE_TDLS:
+ return CRYPTO_AKM_TDLS;
+ case IE_RSN_AKM_SUITE_SAE_SHA256:
+ return CRYPTO_AKM_SAE_SHA256;
+ case IE_RSN_AKM_SUITE_FT_OVER_SAE_SHA256:
+ return CRYPTO_AKM_FT_OVER_SAE_SHA256;
+ case IE_RSN_AKM_SUITE_AP_PEER_KEY_SHA256:
+ return CRYPTO_AKM_AP_PEER_KEY_SHA256;
+ case IE_RSN_AKM_SUITE_8021X_SUITE_B_SHA256:
+ return CRYPTO_AKM_8021X_SUITE_B_SHA256;
+ case IE_RSN_AKM_SUITE_8021X_SUITE_B_SHA384:
+ return CRYPTO_AKM_8021X_SUITE_B_SHA384;
+ case IE_RSN_AKM_SUITE_FT_OVER_8021X_SHA384:
+ return CRYPTO_AKM_FT_OVER_8021X_SHA384;
+ case IE_RSN_AKM_SUITE_FILS_SHA256:
+ return CRYPTO_AKM_FILS_SHA256;
+ case IE_RSN_AKM_SUITE_FILS_SHA384:
+ return CRYPTO_AKM_FILS_SHA384;
+ case IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA256:
+ return CRYPTO_AKM_FT_OVER_FILS_SHA256;
+ case IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA384:
+ return CRYPTO_AKM_FT_OVER_FILS_SHA384;
+ case IE_RSN_AKM_SUITE_OWE:
+ return CRYPTO_AKM_OWE;
+ case IE_RSN_AKM_SUITE_OSEN:
+ return CRYPTO_AKM_OSEN;
+ }
+
+ return 0;
+}
+
+static struct l_genl_msg *netdev_build_cmd_connect(struct netdev *netdev,
+ struct handshake_state *hs,
+ const uint8_t *prev_bssid,
+ const struct iovec *vendor_ies,
+ size_t num_vendor_ies)
+{
+ struct netdev_handshake_state *nhs =
+ l_container_of(hs, struct netdev_handshake_state, super);
+ uint32_t auth_type = IE_AKM_IS_SAE(hs->akm_suite) ?
+ NL80211_AUTHTYPE_SAE :
+ NL80211_AUTHTYPE_OPEN_SYSTEM;
+ enum mpdu_management_subtype subtype = prev_bssid ?
+ MPDU_MANAGEMENT_SUBTYPE_REASSOCIATION_REQUEST :
+ MPDU_MANAGEMENT_SUBTYPE_ASSOCIATION_REQUEST;
+ struct l_genl_msg *msg;
+ struct iovec iov[64];
+ unsigned int n_iov = L_ARRAY_SIZE(iov);
+ unsigned int c_iov = 0;
+ bool is_rsn = hs->supplicant_ie != NULL;
+ uint8_t owe_dh_ie[5 + L_ECC_SCALAR_MAX_BYTES];
+ size_t dh_ie_len;
+
+ msg = l_genl_msg_new_sized(NL80211_CMD_CONNECT, 512);
+ l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &netdev->index);
+ l_genl_msg_append_attr(msg, NL80211_ATTR_WIPHY_FREQ,
+ 4, &netdev->frequency);
+ l_genl_msg_append_attr(msg, NL80211_ATTR_MAC, ETH_ALEN, hs->aa);
+ l_genl_msg_append_attr(msg, NL80211_ATTR_SSID, hs->ssid_len, hs->ssid);
+ l_genl_msg_append_attr(msg, NL80211_ATTR_AUTH_TYPE, 4, &auth_type);
+
+ switch (nhs->type) {
+ case CONNECTION_TYPE_SOFTMAC:
+ case CONNECTION_TYPE_FULLMAC:
+ break;
+ case CONNECTION_TYPE_SAE_OFFLOAD:
+ l_genl_msg_append_attr(msg, NL80211_ATTR_SAE_PASSWORD,
+ strlen(hs->passphrase), hs->passphrase);
+ break;
+ case CONNECTION_TYPE_PSK_OFFLOAD:
+ l_genl_msg_append_attr(msg, NL80211_ATTR_PMK, 32, hs->pmk);
+ break;
+ case CONNECTION_TYPE_8021X_OFFLOAD:
+ l_genl_msg_append_attr(msg, NL80211_ATTR_WANT_1X_4WAY_HS,
+ 0, NULL);
+ }
+
+ if (prev_bssid)
+ l_genl_msg_append_attr(msg, NL80211_ATTR_PREV_BSSID, ETH_ALEN,
+ prev_bssid);
+
+ if (netdev->privacy)
+ l_genl_msg_append_attr(msg, NL80211_ATTR_PRIVACY, 0, NULL);
+
+ l_genl_msg_append_attr(msg, NL80211_ATTR_SOCKET_OWNER, 0, NULL);
+
+ if (is_rsn) {
+ uint32_t nl_cipher;
+ uint32_t nl_akm;
+ uint32_t wpa_version;
+
+ if (hs->pairwise_cipher == IE_RSN_CIPHER_SUITE_CCMP)
+ nl_cipher = CRYPTO_CIPHER_CCMP;
+ else
+ nl_cipher = CRYPTO_CIPHER_TKIP;
+
+ l_genl_msg_append_attr(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
+ 4, &nl_cipher);
+
+ if (hs->group_cipher == IE_RSN_CIPHER_SUITE_CCMP)
+ nl_cipher = CRYPTO_CIPHER_CCMP;
+ else
+ nl_cipher = CRYPTO_CIPHER_TKIP;
+
+ l_genl_msg_append_attr(msg, NL80211_ATTR_CIPHER_SUITE_GROUP,
+ 4, &nl_cipher);
+
+ if (hs->mfp) {
+ uint32_t use_mfp = NL80211_MFP_REQUIRED;
+ l_genl_msg_append_attr(msg, NL80211_ATTR_USE_MFP,
+ 4, &use_mfp);
+ }
+
+ nl_akm = ie_rsn_akm_suite_to_nl80211(hs->akm_suite);
+ if (nl_akm)
+ l_genl_msg_append_attr(msg, NL80211_ATTR_AKM_SUITES,
+ 4, &nl_akm);
+
+ if (IE_AKM_IS_SAE(hs->akm_suite))
+ wpa_version = NL80211_WPA_VERSION_3;
+ else if (hs->wpa_ie)
+ wpa_version = NL80211_WPA_VERSION_1;
+ else
+ wpa_version = NL80211_WPA_VERSION_2;
+
+ l_genl_msg_append_attr(msg, NL80211_ATTR_WPA_VERSIONS,
+ 4, &wpa_version);
+
+ l_genl_msg_append_attr(msg, NL80211_ATTR_CONTROL_PORT, 0, NULL);
+ c_iov = iov_ie_append(iov, n_iov, c_iov, hs->supplicant_ie);
+ }
+
+ if (netdev->owe_sm) {
+ owe_build_dh_ie(netdev->owe_sm, owe_dh_ie, &dh_ie_len);
+ c_iov = iov_ie_append(iov, n_iov, c_iov, owe_dh_ie);
+ }
+
+ if (netdev->pae_over_nl80211)
+ l_genl_msg_append_attr(msg,
+ NL80211_ATTR_CONTROL_PORT_OVER_NL80211,
+ 0, NULL);
+
+ c_iov = iov_ie_append(iov, n_iov, c_iov, hs->mde);
+ c_iov = netdev_populate_common_ies(netdev, hs, msg, iov, n_iov, c_iov);
+
+ mpdu_sort_ies(subtype, iov, c_iov);
+
+ if (vendor_ies && !L_WARN_ON(n_iov - c_iov < num_vendor_ies)) {
+ memcpy(iov + c_iov, vendor_ies,
+ sizeof(*vendor_ies) * num_vendor_ies);
+ c_iov += num_vendor_ies;
+ }
+
+ if (c_iov)
+ l_genl_msg_append_attrv(msg, NL80211_ATTR_IE, iov, c_iov);
+
+ return msg;
+}
+
+static void netdev_cmd_connect_cb(struct l_genl_msg *msg, void *user_data)
+{
+ struct netdev *netdev = user_data;
+
+ netdev->connect_cmd_id = 0;
+
+ if (l_genl_msg_get_error(msg) >= 0) {
+ /*
+ * connected should be false if the connect event hasn't come
+ * in yet. i.e. the CMD_CONNECT ack arrived first (typical).
+ * Mark the connection as 'connected'
+ */
+ if (!netdev->connected)
+ netdev_driver_connected(netdev);
+
+ return;
+ }
+
+ netdev_connect_failed(netdev, NETDEV_RESULT_ASSOCIATION_FAILED,
+ MMPDU_STATUS_CODE_UNSPECIFIED);
+}
+
+static bool netdev_retry_owe(struct netdev *netdev)
+{
+ struct iovec iov;
+
+ if (!owe_next_group(netdev->owe_sm))
+ return false;
+
+ iov.iov_base = netdev->handshake->vendor_ies;
+ iov.iov_len = netdev->handshake->vendor_ies_len;
+
+ netdev->connect_cmd = netdev_build_cmd_connect(netdev,
+ netdev->handshake, NULL, &iov, 1);
+
+ netdev->connect_cmd_id = l_genl_family_send(nl80211,
+ netdev->connect_cmd,
+ netdev_cmd_connect_cb, netdev,
+ NULL);
+
+ if (!netdev->connect_cmd_id)
+ return false;
+
+ netdev->connect_cmd = NULL;
+
+ return true;
+}
+
static void netdev_connect_event(struct l_genl_msg *msg, struct netdev *netdev)
{
struct l_genl_attr attr;
@@ -2162,6 +2390,14 @@ static void netdev_connect_event(struct l_genl_msg *msg, struct netdev *netdev)
goto error;
}
+ if (netdev->owe_sm && status_code && *status_code ==
+ MMPDU_STATUS_CODE_UNSUPP_FINITE_CYCLIC_GROUP) {
+ if (!netdev_retry_owe(netdev))
+ goto error;
+
+ return;
+ }
+
/* AP Rejected the authenticate / associate */
if (!status_code || *status_code != 0)
goto error;
@@ -2175,8 +2411,12 @@ process_resp_ies:
if (resp_ies) {
const uint8_t *fte = NULL;
const uint8_t *qos_set = NULL;
+ const uint8_t *owe_dh = NULL;
+ size_t owe_dh_len = 0;
size_t qos_len = 0;
struct ie_ft_info ft_info;
+ struct ie_rsn_info info;
+ bool owe_akm_found = false;
ie_tlv_iter_init(&iter, resp_ies, resp_ies_len);
@@ -2203,7 +2443,53 @@ process_resp_ies:
data - 3,
ie_tlv_iter_get_length(&iter) + 3);
break;
+ case IE_TYPE_OWE_DH_PARAM:
+ if (!netdev->owe_sm)
+ continue;
+
+ owe_dh = data;
+ owe_dh_len = len;
+
+ break;
+
+ case IE_TYPE_RSN:
+ if (!netdev->owe_sm)
+ continue;
+
+ if (ie_parse_rsne(&iter, &info) < 0) {
+ l_error("could not parse RSN IE");
+ goto error;
+ }
+
+ /*
+ * RFC 8110 Section 4.2
+ * An AP agreeing to do OWE MUST include the OWE AKM in
+ * the RSN element portion of the 802.11 association
+ * response.
+ */
+ if (info.akm_suites != IE_RSN_AKM_SUITE_OWE) {
+ l_error("OWE AKM not included");
+ goto error;
+ }
+
+ owe_akm_found = true;
+
+ break;
+ }
+ }
+
+ if (netdev->owe_sm) {
+ if (!owe_dh || !owe_akm_found) {
+ l_error("OWE DH element/RSN not found");
+ goto error;
}
+
+ if (owe_process_dh_ie(netdev->owe_sm, owe_dh,
+ owe_dh_len) != 0)
+ goto error;
+
+ owe_sm_free(netdev->owe_sm);
+ netdev->owe_sm = NULL;
}
/* FILS handles its own FT key derivation */
@@ -2271,52 +2557,6 @@ deauth:
netdev, NULL);
}
-static unsigned int ie_rsn_akm_suite_to_nl80211(enum ie_rsn_akm_suite akm)
-{
- switch (akm) {
- case IE_RSN_AKM_SUITE_8021X:
- return CRYPTO_AKM_8021X;
- case IE_RSN_AKM_SUITE_PSK:
- return CRYPTO_AKM_PSK;
- case IE_RSN_AKM_SUITE_FT_OVER_8021X:
- return CRYPTO_AKM_FT_OVER_8021X;
- case IE_RSN_AKM_SUITE_FT_USING_PSK:
- return CRYPTO_AKM_FT_USING_PSK;
- case IE_RSN_AKM_SUITE_8021X_SHA256:
- return CRYPTO_AKM_8021X_SHA256;
- case IE_RSN_AKM_SUITE_PSK_SHA256:
- return CRYPTO_AKM_PSK_SHA256;
- case IE_RSN_AKM_SUITE_TDLS:
- return CRYPTO_AKM_TDLS;
- case IE_RSN_AKM_SUITE_SAE_SHA256:
- return CRYPTO_AKM_SAE_SHA256;
- case IE_RSN_AKM_SUITE_FT_OVER_SAE_SHA256:
- return CRYPTO_AKM_FT_OVER_SAE_SHA256;
- case IE_RSN_AKM_SUITE_AP_PEER_KEY_SHA256:
- return CRYPTO_AKM_AP_PEER_KEY_SHA256;
- case IE_RSN_AKM_SUITE_8021X_SUITE_B_SHA256:
- return CRYPTO_AKM_8021X_SUITE_B_SHA256;
- case IE_RSN_AKM_SUITE_8021X_SUITE_B_SHA384:
- return CRYPTO_AKM_8021X_SUITE_B_SHA384;
- case IE_RSN_AKM_SUITE_FT_OVER_8021X_SHA384:
- return CRYPTO_AKM_FT_OVER_8021X_SHA384;
- case IE_RSN_AKM_SUITE_FILS_SHA256:
- return CRYPTO_AKM_FILS_SHA256;
- case IE_RSN_AKM_SUITE_FILS_SHA384:
- return CRYPTO_AKM_FILS_SHA384;
- case IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA256:
- return CRYPTO_AKM_FT_OVER_FILS_SHA256;
- case IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA384:
- return CRYPTO_AKM_FT_OVER_FILS_SHA384;
- case IE_RSN_AKM_SUITE_OWE:
- return CRYPTO_AKM_OWE;
- case IE_RSN_AKM_SUITE_OSEN:
- return CRYPTO_AKM_OSEN;
- }
-
- return 0;
-}
-
static struct l_genl_msg *netdev_build_cmd_associate_common(
struct netdev *netdev)
{
@@ -2602,28 +2842,6 @@ assoc_failed:
netdev->expect_connect_failure = true;
}
-static void netdev_cmd_connect_cb(struct l_genl_msg *msg, void *user_data)
-{
- struct netdev *netdev = user_data;
-
- netdev->connect_cmd_id = 0;
-
- if (l_genl_msg_get_error(msg) >= 0) {
- /*
- * connected should be false if the connect event hasn't come
- * in yet. i.e. the CMD_CONNECT ack arrived first (typical).
- * Mark the connection as 'connected'
- */
- if (!netdev->connected)
- netdev_driver_connected(netdev);
-
- return;
- }
-
- netdev_connect_failed(netdev, NETDEV_RESULT_ASSOCIATION_FAILED,
- MMPDU_STATUS_CODE_UNSPECIFIED);
-}
-
static struct l_genl_msg *netdev_build_cmd_authenticate(struct netdev *netdev,
uint32_t auth_type)
{
@@ -2777,64 +2995,6 @@ static void netdev_sae_tx_associate(void *user_data)
}
}
-static void netdev_owe_tx_authenticate(void *user_data)
-{
- struct netdev *netdev = user_data;
- struct l_genl_msg *msg;
-
- msg = netdev_build_cmd_authenticate(netdev,
- NL80211_AUTHTYPE_OPEN_SYSTEM);
-
- if (!l_genl_family_send(nl80211, msg, netdev_auth_cb,
- netdev, NULL)) {
- l_genl_msg_unref(msg);
- netdev_connect_failed(netdev,
- NETDEV_RESULT_AUTHENTICATION_FAILED,
- MMPDU_STATUS_CODE_UNSPECIFIED);
- return;
- }
-
- netdev->auth_cmd = l_genl_msg_ref(msg);
-}
-
-static void netdev_owe_tx_associate(struct iovec *owe_iov, size_t n_owe_iov,
- void *user_data)
-{
- struct netdev *netdev = user_data;
- struct handshake_state *hs = netdev->handshake;
- struct l_genl_msg *msg;
- struct iovec iov[64];
- unsigned int n_iov = L_ARRAY_SIZE(iov);
- unsigned int c_iov = 0;
- enum mpdu_management_subtype subtype =
- MPDU_MANAGEMENT_SUBTYPE_ASSOCIATION_REQUEST;
-
- msg = netdev_build_cmd_associate_common(netdev);
-
- c_iov = netdev_populate_common_ies(netdev, hs, msg, iov, n_iov, c_iov);
-
- if (!L_WARN_ON(n_iov - c_iov < n_owe_iov)) {
- memcpy(iov + c_iov, owe_iov, sizeof(*owe_iov) * n_owe_iov);
- c_iov += n_owe_iov;
- }
-
- mpdu_sort_ies(subtype, iov, c_iov);
-
- l_genl_msg_append_attrv(msg, NL80211_ATTR_IE, iov, c_iov);
-
- /* If doing a non-FT Reassociation */
- if (netdev->in_reassoc)
- l_genl_msg_append_attr(msg, NL80211_ATTR_PREV_BSSID, 6,
- netdev->ap->prev_bssid);
-
- if (!l_genl_family_send(nl80211, msg, netdev_assoc_cb,
- netdev, NULL)) {
- l_genl_msg_unref(msg);
- netdev_connect_failed(netdev, NETDEV_RESULT_ASSOCIATION_FAILED,
- MMPDU_STATUS_CODE_UNSPECIFIED);
- }
-}
-
static void netdev_fils_tx_authenticate(const uint8_t *body,
size_t body_len,
void *user_data)
@@ -2902,127 +3062,6 @@ static void netdev_fils_tx_associate(struct iovec *fils_iov, size_t n_fils_iov,
}
}
-static struct l_genl_msg *netdev_build_cmd_connect(struct netdev *netdev,
- struct handshake_state *hs,
- const uint8_t *prev_bssid,
- const struct iovec *vendor_ies,
- size_t num_vendor_ies)
-{
- struct netdev_handshake_state *nhs =
- l_container_of(hs, struct netdev_handshake_state, super);
- uint32_t auth_type = IE_AKM_IS_SAE(hs->akm_suite) ?
- NL80211_AUTHTYPE_SAE :
- NL80211_AUTHTYPE_OPEN_SYSTEM;
- enum mpdu_management_subtype subtype = prev_bssid ?
- MPDU_MANAGEMENT_SUBTYPE_REASSOCIATION_REQUEST :
- MPDU_MANAGEMENT_SUBTYPE_ASSOCIATION_REQUEST;
- struct l_genl_msg *msg;
- struct iovec iov[64];
- unsigned int n_iov = L_ARRAY_SIZE(iov);
- unsigned int c_iov = 0;
- bool is_rsn = hs->supplicant_ie != NULL;
-
- msg = l_genl_msg_new_sized(NL80211_CMD_CONNECT, 512);
- l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &netdev->index);
- l_genl_msg_append_attr(msg, NL80211_ATTR_WIPHY_FREQ,
- 4, &netdev->frequency);
- l_genl_msg_append_attr(msg, NL80211_ATTR_MAC, ETH_ALEN, hs->aa);
- l_genl_msg_append_attr(msg, NL80211_ATTR_SSID, hs->ssid_len, hs->ssid);
- l_genl_msg_append_attr(msg, NL80211_ATTR_AUTH_TYPE, 4, &auth_type);
-
- switch (nhs->type) {
- case CONNECTION_TYPE_SOFTMAC:
- case CONNECTION_TYPE_FULLMAC:
- break;
- case CONNECTION_TYPE_SAE_OFFLOAD:
- l_genl_msg_append_attr(msg, NL80211_ATTR_SAE_PASSWORD,
- strlen(hs->passphrase), hs->passphrase);
- break;
- case CONNECTION_TYPE_PSK_OFFLOAD:
- l_genl_msg_append_attr(msg, NL80211_ATTR_PMK, 32, hs->pmk);
- break;
- case CONNECTION_TYPE_8021X_OFFLOAD:
- l_genl_msg_append_attr(msg, NL80211_ATTR_WANT_1X_4WAY_HS,
- 0, NULL);
- }
-
- if (prev_bssid)
- l_genl_msg_append_attr(msg, NL80211_ATTR_PREV_BSSID, ETH_ALEN,
- prev_bssid);
-
- if (netdev->privacy)
- l_genl_msg_append_attr(msg, NL80211_ATTR_PRIVACY, 0, NULL);
-
- l_genl_msg_append_attr(msg, NL80211_ATTR_SOCKET_OWNER, 0, NULL);
-
- if (is_rsn) {
- uint32_t nl_cipher;
- uint32_t nl_akm;
- uint32_t wpa_version;
-
- if (hs->pairwise_cipher == IE_RSN_CIPHER_SUITE_CCMP)
- nl_cipher = CRYPTO_CIPHER_CCMP;
- else
- nl_cipher = CRYPTO_CIPHER_TKIP;
-
- l_genl_msg_append_attr(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
- 4, &nl_cipher);
-
- if (hs->group_cipher == IE_RSN_CIPHER_SUITE_CCMP)
- nl_cipher = CRYPTO_CIPHER_CCMP;
- else
- nl_cipher = CRYPTO_CIPHER_TKIP;
-
- l_genl_msg_append_attr(msg, NL80211_ATTR_CIPHER_SUITE_GROUP,
- 4, &nl_cipher);
-
- if (hs->mfp) {
- uint32_t use_mfp = NL80211_MFP_REQUIRED;
- l_genl_msg_append_attr(msg, NL80211_ATTR_USE_MFP,
- 4, &use_mfp);
- }
-
- nl_akm = ie_rsn_akm_suite_to_nl80211(hs->akm_suite);
- if (nl_akm)
- l_genl_msg_append_attr(msg, NL80211_ATTR_AKM_SUITES,
- 4, &nl_akm);
-
- if (IE_AKM_IS_SAE(hs->akm_suite))
- wpa_version = NL80211_WPA_VERSION_3;
- else if (hs->wpa_ie)
- wpa_version = NL80211_WPA_VERSION_1;
- else
- wpa_version = NL80211_WPA_VERSION_2;
-
- l_genl_msg_append_attr(msg, NL80211_ATTR_WPA_VERSIONS,
- 4, &wpa_version);
-
- l_genl_msg_append_attr(msg, NL80211_ATTR_CONTROL_PORT, 0, NULL);
- c_iov = iov_ie_append(iov, n_iov, c_iov, hs->supplicant_ie);
- }
-
- if (netdev->pae_over_nl80211)
- l_genl_msg_append_attr(msg,
- NL80211_ATTR_CONTROL_PORT_OVER_NL80211,
- 0, NULL);
-
- c_iov = iov_ie_append(iov, n_iov, c_iov, hs->mde);
- c_iov = netdev_populate_common_ies(netdev, hs, msg, iov, n_iov, c_iov);
-
- mpdu_sort_ies(subtype, iov, c_iov);
-
- if (vendor_ies && !L_WARN_ON(n_iov - c_iov < num_vendor_ies)) {
- memcpy(iov + c_iov, vendor_ies,
- sizeof(*vendor_ies) * num_vendor_ies);
- c_iov += num_vendor_ies;
- }
-
- if (c_iov)
- l_genl_msg_append_attrv(msg, NL80211_ATTR_IE, iov, c_iov);
-
- return msg;
-}
-
struct rtnl_data {
struct netdev *netdev;
uint8_t addr[ETH_ALEN];
@@ -3397,6 +3436,8 @@ static int netdev_handshake_state_setup_connection_type(
NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK))
goto psk_offload;
+ /* fall through */
+ case IE_RSN_AKM_SUITE_OWE:
if (softmac)
goto softmac;
@@ -3425,12 +3466,11 @@ static int netdev_handshake_state_setup_connection_type(
goto softmac;
return -EINVAL;
- case IE_RSN_AKM_SUITE_OWE:
case IE_RSN_AKM_SUITE_FILS_SHA256:
case IE_RSN_AKM_SUITE_FILS_SHA384:
case IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA256:
case IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA384:
- /* FILS and OWE have no offload in any upstream driver */
+ /* FILS has no offload in any upstream driver */
if (softmac)
goto softmac;
@@ -3509,10 +3549,9 @@ static void netdev_connect_common(struct netdev *netdev,
break;
case IE_RSN_AKM_SUITE_OWE:
- netdev->ap = owe_sm_new(hs, netdev_owe_tx_authenticate,
- netdev_owe_tx_associate,
- netdev);
- break;
+ netdev->owe_sm = owe_sm_new(hs);
+
+ goto build_cmd_connect;
case IE_RSN_AKM_SUITE_FILS_SHA256:
case IE_RSN_AKM_SUITE_FILS_SHA384:
case IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA256:
diff --git a/src/netdev.h b/src/netdev.h
index 0094d5f9..e5698894 100644
--- a/src/netdev.h
+++ b/src/netdev.h
@@ -28,6 +28,7 @@ struct handshake_state;
struct eapol_sm;
struct mmpdu_header;
struct diagnostic_station_info;
+struct owe_sm;
enum netdev_result {
NETDEV_RESULT_OK,
diff --git a/src/owe.c b/src/owe.c
index b1eea025..eed3e266 100644
--- a/src/owe.c
+++ b/src/owe.c
@@ -34,7 +34,6 @@
#include "src/auth-proto.h"
struct owe_sm {
- struct auth_proto ap;
struct handshake_state *hs;
const struct l_ecc_curve *curve;
struct l_ecc_scalar *private;
@@ -42,10 +41,6 @@ struct owe_sm {
uint8_t retry;
uint16_t group;
const unsigned int *ecc_groups;
-
- owe_tx_authenticate_func_t auth_tx;
- owe_tx_associate_func_t assoc_tx;
- void *user_data;
};
static bool owe_reset(struct owe_sm *owe)
@@ -72,62 +67,28 @@ static bool owe_reset(struct owe_sm *owe)
return true;
}
-static void owe_free(struct auth_proto *ap)
+void owe_sm_free(struct owe_sm *owe)
{
- struct owe_sm *owe = l_container_of(ap, struct owe_sm, ap);
-
l_ecc_scalar_free(owe->private);
l_ecc_point_free(owe->public_key);
l_free(owe);
}
-static bool owe_start(struct auth_proto *ap)
+void owe_build_dh_ie(struct owe_sm *owe, uint8_t *buf, size_t *len_out)
{
- struct owe_sm *owe = l_container_of(ap, struct owe_sm, ap);
-
- owe->auth_tx(owe->user_data);
-
- return true;
-}
-
-static int owe_rx_authenticate(struct auth_proto *ap, const uint8_t *frame,
- size_t frame_len)
-{
- struct owe_sm *owe = l_container_of(ap, struct owe_sm, ap);
-
- uint8_t buf[5 + L_ECC_SCALAR_MAX_BYTES];
- struct iovec iov[3];
- int iov_elems = 0;
- size_t len;
-
- /*
- * RFC 8110 Section 4.3
- * A client wishing to do OWE MUST indicate the OWE AKM in the RSN
- * element portion of the 802.11 association request ...
- */
- iov[iov_elems].iov_base = owe->hs->supplicant_ie;
- iov[iov_elems].iov_len = owe->hs->supplicant_ie[1] + 2;
- iov_elems++;
-
/*
- * ... and MUST include a Diffie-Hellman Parameter element to its
- * 802.11 association request.
+ * A client wishing to do OWE ... MUST include a Diffie-Hellman
+ * Parameter element to its 802.11 association request.
*/
buf[0] = IE_TYPE_EXTENSION;
buf[2] = IE_TYPE_OWE_DH_PARAM - 256;
l_put_le16(owe->group, buf + 3); /* group */
- len = l_ecc_point_get_x(owe->public_key, buf + 5,
+ *len_out = l_ecc_point_get_x(owe->public_key, buf + 5,
L_ECC_SCALAR_MAX_BYTES);
- buf[1] = 3 + len; /* length */
-
- iov[iov_elems].iov_base = (void *) buf;
- iov[iov_elems].iov_len = buf[1] + 2;
- iov_elems++;
+ buf[1] = 3 + *len_out; /* length */
- owe->assoc_tx(iov, iov_elems, owe->user_data);
-
- return 0;
+ *len_out += 5;
}
/*
@@ -220,7 +181,7 @@ failed:
return false;
}
-static bool owe_retry(struct owe_sm *owe)
+bool owe_next_group(struct owe_sm *owe)
{
/* retry with another group, if possible */
owe->retry++;
@@ -228,88 +189,23 @@ static bool owe_retry(struct owe_sm *owe)
if (!owe_reset(owe))
return false;
- l_debug("OWE retrying with group %u", owe->group);
-
- owe_rx_authenticate(&owe->ap, NULL, 0);
-
return true;
}
-static int owe_rx_associate(struct auth_proto *ap, const uint8_t *frame,
- size_t len)
+int owe_process_dh_ie(struct owe_sm *owe, const uint8_t *dh, size_t len)
{
- struct owe_sm *owe = l_container_of(ap, struct owe_sm, ap);
-
- const struct mmpdu_header *mpdu = (const struct mmpdu_header *) frame;
- const struct mmpdu_association_response *body = mmpdu_body(mpdu);
- struct ie_tlv_iter iter;
- size_t owe_dh_len = 0;
- const uint8_t *owe_dh = NULL;
- struct ie_rsn_info info;
- bool akm_found = false;
- const void *data;
-
- if (L_LE16_TO_CPU(body->status_code) ==
- MMPDU_STATUS_CODE_UNSUPP_FINITE_CYCLIC_GROUP) {
- if (!owe_retry(owe))
- goto owe_bad_status;
-
- return -EAGAIN;
- } else if (body->status_code)
- goto owe_bad_status;
-
- ie_tlv_iter_init(&iter, body->ies, (const uint8_t *) mpdu + len -
- body->ies);
-
- while (ie_tlv_iter_next(&iter)) {
- uint16_t tag = ie_tlv_iter_get_tag(&iter);
-
- data = ie_tlv_iter_get_data(&iter);
- len = ie_tlv_iter_get_length(&iter);
-
- switch (tag) {
- case IE_TYPE_OWE_DH_PARAM:
- owe_dh = data;
- owe_dh_len = len;
-
- break;
- case IE_TYPE_RSN:
- if (ie_parse_rsne(&iter, &info) < 0) {
- l_error("could not parse RSN IE");
- goto invalid_ies;
- }
-
- /*
- * RFC 8110 Section 4.2
- * An AP agreeing to do OWE MUST include the OWE AKM in
- * the RSN element portion of the 802.11 association
- * response.
- */
- if (info.akm_suites != IE_RSN_AKM_SUITE_OWE) {
- l_error("OWE AKM not included");
- goto invalid_ies;
- }
-
- akm_found = true;
-
- break;
- default:
- continue;
- }
- }
-
- if (!owe_dh || owe_dh_len < 34 || !akm_found) {
+ if (!dh || len < 34) {
l_error("associate response did not include proper OWE IE's");
goto invalid_ies;
}
- if (l_get_le16(owe_dh) != owe->group) {
+ if (l_get_le16(dh) != owe->group) {
l_error("associate response contained unsupported group %u",
- l_get_le16(owe_dh));
+ l_get_le16(dh));
return -EBADMSG;
}
- if (!owe_compute_keys(owe, owe_dh + 2, owe_dh_len - 2)) {
+ if (!owe_compute_keys(owe, dh + 2, len - 2)) {
l_error("could not compute OWE keys");
return -EBADMSG;
}
@@ -318,33 +214,19 @@ static int owe_rx_associate(struct auth_proto *ap, const uint8_t *frame,
invalid_ies:
return MMPDU_STATUS_CODE_INVALID_ELEMENT;
-
-owe_bad_status:
- return L_LE16_TO_CPU(body->status_code);
}
-struct auth_proto *owe_sm_new(struct handshake_state *hs,
- owe_tx_authenticate_func_t auth,
- owe_tx_associate_func_t assoc,
- void *user_data)
+struct owe_sm *owe_sm_new(struct handshake_state *hs)
{
struct owe_sm *owe = l_new(struct owe_sm, 1);
owe->hs = hs;
- owe->auth_tx = auth;
- owe->assoc_tx = assoc;
- owe->user_data = user_data;
owe->ecc_groups = l_ecc_supported_ike_groups();
- owe->ap.start = owe_start;
- owe->ap.free = owe_free;
- owe->ap.rx_authenticate = owe_rx_authenticate;
- owe->ap.rx_associate = owe_rx_associate;
-
if (!owe_reset(owe)) {
l_free(owe);
return NULL;
}
- return &owe->ap;
+ return owe;
}
diff --git a/src/owe.h b/src/owe.h
index 9a21505f..8a734a00 100644
--- a/src/owe.h
+++ b/src/owe.h
@@ -23,11 +23,9 @@
struct owe_sm;
struct handshake_state;
-typedef void (*owe_tx_authenticate_func_t)(void *user_data);
-typedef void (*owe_tx_associate_func_t)(struct iovec *ie_iov, size_t iov_len,
- void *user_data);
+struct owe_sm *owe_sm_new(struct handshake_state *hs);
+void owe_sm_free(struct owe_sm *sm);
-struct auth_proto *owe_sm_new(struct handshake_state *hs,
- owe_tx_authenticate_func_t auth,
- owe_tx_associate_func_t assoc,
- void *user_data);
+void owe_build_dh_ie(struct owe_sm *sm, uint8_t *buf, size_t *len_out);
+int owe_process_dh_ie(struct owe_sm *sm, const uint8_t *dh, size_t len);
+bool owe_next_group(struct owe_sm *sm);
--
2.31.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2021-09-03 19:26 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-03 19:26 [PATCH v2 1/3] netdev: factor out scan_bss from CMD_CONNECT builder James Prestwood
2021-09-03 19:26 ` [PATCH v2 2/3] wsc: set ssid in handshake James Prestwood
2021-09-03 19:26 ` [PATCH v2 3/3] owe: netdev: refactor to remove OWE as an auth-proto James Prestwood
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.