Message ID | 20170221123758.5339-1-johannes@sipsolutions.net (mailing list archive) |
---|---|
State | RFC |
Delegated to: | Johannes Berg |
Headers | show |
On Tue, Feb 21, 2017 at 01:37:57PM +0100, Johannes Berg wrote: > Add a new NL80211_ATTR_PMK attribute that might be passed as part > of NL80211_CMD_CONNECT command, and contain the PSK (which is the > PMK, hence the name.) > diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h > +#define WLAN_PMK_LEN 32 > diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h > struct cfg80211_crypto_settings { > + const u8 *psk; > diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c > + [NL80211_ATTR_PMK] = { .len = WLAN_PMK_LEN }, While the existing WPA2-PSK cases all use 32 octet PMK, there are also 48 octet PMKs in use with EAP (Suite B 192-bit level and FILS with SHA384). Patch 2/2 seemed to look at the PMK length as well.. Should the same be done already with 1/2 so that the PSK case is separately validating exact match with 32 octets in length for PMK = PSK while the other cases allow longer PMK as well? I never remember how the attr policy .len works, so that may already be the implicit behavior here, but it would be clearer to be more explicit about the possible lengths of the WLAN_ATTR_PMK and not assume that WLAN_PMK_LEN definition is the only possible option.
> While the existing WPA2-PSK cases all use 32 octet PMK, there are > also > 48 octet PMKs in use with EAP (Suite B 192-bit level and FILS with > SHA384). Patch 2/2 seemed to look at the PMK length as well.. Should > the same be done already with 1/2 so that the PSK case is separately > validating exact match with 32 octets in length for PMK = PSK while > the other cases allow longer PMK as well? > > I never remember how the attr policy .len works, so that may already > be the implicit behavior here, but it would be clearer to be more > explicit about the possible lengths of the WLAN_ATTR_PMK and not > assume that WLAN_PMK_LEN definition is the only possible option. The .len verifies that it's at least that long. We're thus ignoring additional bytes in the PSK case if they're present, which I suppose we should fix by checking the exact length in the code separately. johannes
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 6ea381c98aae..2049e983a994 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -2357,6 +2357,7 @@ enum ieee80211_sa_query_action { #define WLAN_MAX_KEY_LEN 32 #define WLAN_PMKID_LEN 16 +#define WLAN_PMK_LEN 32 #define WLAN_OUI_WFA 0x506f9a #define WLAN_OUI_TYPE_WFA_P2P 9 diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 86c12f85fb53..4ca968927d60 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -643,6 +643,7 @@ struct survey_info { * @wep_keys: static WEP keys, if not NULL points to an array of * CFG80211_MAX_WEP_KEYS WEP keys * @wep_tx_key: key index (0..3) of the default TX static WEP key + * @psk: PSK (for devices supporting 4-way-handshake offload) */ struct cfg80211_crypto_settings { u32 wpa_versions; @@ -656,6 +657,7 @@ struct cfg80211_crypto_settings { bool control_port_no_encrypt; struct key_params *wep_keys; int wep_tx_key; + const u8 *psk; }; /** diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 9a499b15cfbc..bb5e1904a107 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -2012,6 +2012,9 @@ enum nl80211_commands { * u32 attribute with an &enum nl80211_timeout_reason value. This is used, * e.g., with %NL80211_CMD_CONNECT event. * + * @NL80211_ATTR_PMK: PSK for offloaded 4-Way Handshake. Relevant only + * with %NL80211_CMD_CONNECT (for WPA/WPA2-PSK networks). + * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -2423,6 +2426,8 @@ enum nl80211_attrs { NL80211_ATTR_TIMEOUT_REASON, + NL80211_ATTR_PMK, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -4759,6 +4764,9 @@ enum nl80211_feature_flags { * @NL80211_EXT_FEATURE_CQM_RSSI_LIST: With this driver the * %NL80211_ATTR_CQM_RSSI_THOLD attribute accepts a list of zero or more * RSSI threshold values to monitor rather than exactly one threshold. + * @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK: Device supports doing 4-way + * handshake with PSK in station mode (PSK is passed as part of the connect + * and associate commands). * * @NUM_NL80211_EXT_FEATURES: number of extended features. * @MAX_NL80211_EXT_FEATURES: highest extended feature index. @@ -4778,6 +4786,7 @@ enum nl80211_ext_feature_index { NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED, NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI, NL80211_EXT_FEATURE_CQM_RSSI_LIST, + NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK, /* add new features before the definition below */ NUM_NL80211_EXT_FEATURES, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d516527fcb8e..494b50b3eb71 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -410,6 +410,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { .len = sizeof(struct nl80211_bss_select_rssi_adjust) }, [NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 }, + [NL80211_ATTR_PMK] = { .len = WLAN_PMK_LEN }, }; /* policy for the key attributes */ @@ -8039,6 +8040,13 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, memcpy(settings->akm_suites, data, len); } + if (info->attrs[NL80211_ATTR_PMK]) { + if (!wiphy_ext_feature_isset(&rdev->wiphy, + NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK)) + return -EINVAL; + settings->psk = nla_data(info->attrs[NL80211_ATTR_PMK]); + } + return 0; }