The IEEE 802.11bi standard introduces the Enhanced Privacy Protection Key Exchange (EPPKE) authentication protocol as specified in "IEEE P802.11bi/D3.0, 12.16.9". This protocol requires selecting a hash algorithm such as SHA-256, SHA-384, or SHA-512 to use for Message Integrity Code (MIC) computation and for generating the hash of the Authentication frame. Add a new netlink attribute, NL80211_ATTR_HASH_ALG, to allow userspace to provide the hash algorithm via the NL80211_CMD_AUTHENTICATE command. This attribute is only present when the connection uses the EPPKE authentication protocol. Extend struct cfg80211_auth_request with a hash_alg field to carry the hash algorithm from cfg80211 to the mac80211 layer. Signed-off-by: Kavita Kavita --- include/net/cfg80211.h | 3 +++ include/uapi/linux/nl80211.h | 36 ++++++++++++++++++++++++++++++++++++ net/wireless/nl80211.c | 9 +++++++++ 3 files changed, 48 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 6f02d2fdfc71..8f2ad094779f 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -3200,6 +3200,8 @@ static inline const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 id) * given an MLD address) by the driver * @ap_mld_addr: AP MLD address in case of authentication request with * an AP MLD, valid iff @link_id >= 0 + * @hash_alg: Hash algorithm defined in @enum nl80211_hash_alg used in EPPKE + * Authentication. */ struct cfg80211_auth_request { struct cfg80211_bss *bss; @@ -3217,6 +3219,7 @@ struct cfg80211_auth_request { size_t auth_data_len; s8 link_id; const u8 *ap_mld_addr; + u32 hash_alg; }; /** diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index d0008780ffcb..0074fccd4b51 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -2987,6 +2987,13 @@ enum nl80211_commands { * as specified in "IEEE P802.11bi/D3.0, 12.16.9", this attribute * is used for MIC calculation. * + * @NL80211_ATTR_HASH_ALG: (u32) Hash algorithm used both for Message Integrity + * Code (MIC) computation and for generating the hash of the Authentication + * frame in the Enhanced Privacy Protection Key Exchange (EPPKE) + * authentication protocol as specified in "IEEE P802.11bi/D3.0, 12.16.9". + * This attribute is used with %NL80211_CMD_AUTHENTICATE. + * See &enum nl80211_hash_alg for details. + * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -3559,6 +3566,8 @@ enum nl80211_attrs { NL80211_ATTR_KEY_KCK, + NL80211_ATTR_HASH_ALG, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -8463,4 +8472,31 @@ enum nl80211_nan_capabilities { NL80211_NAN_CAPABILITIES_MAX = __NL80211_NAN_CAPABILITIES_LAST - 1, }; +/** + * enum nl80211_hash_alg - Hash algorithms used in EPPKE + * + * @__NL80211_HASH_ALG_INVALID: invalid, not used + * @NL80211_HASH_ALG_SHA256: SHA-256 + * @NL80211_HASH_ALG_SHA384: SHA-384 + * @NL80211_HASH_ALG_SHA512: SHA-512 + * @__NL80211_HASH_ALG_LAST: internal use + * @NL80211_HASH_ALG_MAX: highest hash algorithm number currently defined + * + * These values are used with %NL80211_ATTR_HASH_ALG to select the hash + * algorithm used both for computing the MIC and for generating the hash + * of the Authentication frame in the EPPKE authentication protocol. + */ + +enum nl80211_hash_alg { + __NL80211_HASH_ALG_INVALID, + + NL80211_HASH_ALG_SHA256, + NL80211_HASH_ALG_SHA384, + NL80211_HASH_ALG_SHA512, + + /* keep last */ + __NL80211_HASH_ALG_LAST, + NL80211_HASH_ALG_MAX = __NL80211_HASH_ALG_LAST - 1 +}; + #endif /* __LINUX_NL80211_H */ diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d890d0f25191..c83252cfc0bb 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -935,6 +935,9 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { [NL80211_ATTR_KEY_PREASSOC] = { .type = NLA_FLAG }, [NL80211_ATTR_KEY_KCK] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN }, + [NL80211_ATTR_HASH_ALG] = { .type = NLA_U32, + .min = NL80211_HASH_ALG_SHA256, + .max = NL80211_HASH_ALG_MAX }, }; /* policy for the key attributes */ @@ -12035,6 +12038,12 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) akm_suite = get_unaligned_be32(akm_list); if (!cfg80211_is_sae_akmp(akm_suite)) return -EINVAL; + + if (!info->attrs[NL80211_ATTR_HASH_ALG]) + return -EINVAL; + + req.hash_alg = + nla_get_u32(info->attrs[NL80211_ATTR_HASH_ALG]); } if (auth_trans == 3) { -- 2.34.1