summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSunil Dutt <usdutt@codeaurora.org>2019-02-20 05:48:07 -0500
committerJohannes Berg <johannes.berg@intel.com>2019-04-08 08:32:23 -0400
commitcb74e9775871f8c82a1297cf76209f10ab5bbe3d (patch)
treef17928d0d617ee9a66dc5826ea5b8426c9135e1b
parentab60633c7136c300f15a390f3469d7c4be15a055 (diff)
cfg80211/nl80211: Offload OWE processing to user space in AP mode
This interface allows the host driver to offload OWE processing to user space. This intends to support OWE (Opportunistic Wireless Encryption) AKM by the drivers that implement SME but rely on the user space for the cryptographic/OWE processing in AP mode. Such drivers are not capable of processing/deriving the DH IE. A new NL80211 command - NL80211_CMD_UPDATE_OWE_INFO is introduced to send the request/event between the host driver and user space. Driver shall provide the OWE info (MAC address and DH IE) of the peer to user space for cryptographic processing of the DH IE through the event. Accordingly, the user space shall update the OWE info/DH IE to the driver. Following is the sequence in AP mode for OWE authentication. Driver passes the OWE info obtained from the peer in the Association Request to the user space through the event cfg80211_update_owe_info_event. User space shall process the OWE info received and generate new OWE info. This OWE info is passed to the driver through NL80211_CMD_UPDATE_OWE_INFO request. Driver eventually uses this OWE info to send the Association Response to the peer. This OWE info in the command interface carries the IEs that include PMKID of the peer if the PMKSA is still valid or an updated DH IE for generating a new PMKSA with the peer. Signed-off-by: Liangwei Dong <liangwei@codeaurora.org> Signed-off-by: Sunil Dutt <usdutt@codeaurora.org> Signed-off-by: Srinivas Dasari <dasaris@codeaurora.org> [remove policy initialization - no longer exists] Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--include/net/cfg80211.h42
-rw-r--r--include/uapi/linux/nl80211.h7
-rw-r--r--net/wireless/nl80211.c72
-rw-r--r--net/wireless/rdev-ops.h13
-rw-r--r--net/wireless/trace.h38
5 files changed, 172 insertions, 0 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 5859a5e02454..70432fd638af 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3111,6 +3111,32 @@ struct cfg80211_pmsr_request {
3111}; 3111};
3112 3112
3113/** 3113/**
3114 * struct cfg80211_update_owe_info - OWE Information
3115 *
3116 * This structure provides information needed for the drivers to offload OWE
3117 * (Opportunistic Wireless Encryption) processing to the user space.
3118 *
3119 * Commonly used across update_owe_info request and event interfaces.
3120 *
3121 * @peer: MAC address of the peer device for which the OWE processing
3122 * has to be done.
3123 * @status: status code, %WLAN_STATUS_SUCCESS for successful OWE info
3124 * processing, use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space
3125 * cannot give you the real status code for failures. Used only for
3126 * OWE update request command interface (user space to driver).
3127 * @ie: IEs obtained from the peer or constructed by the user space. These are
3128 * the IEs of the remote peer in the event from the host driver and
3129 * the constructed IEs by the user space in the request interface.
3130 * @ie_len: Length of IEs in octets.
3131 */
3132struct cfg80211_update_owe_info {
3133 u8 peer[ETH_ALEN] __aligned(2);
3134 u16 status;
3135 const u8 *ie;
3136 size_t ie_len;
3137};
3138
3139/**
3114 * struct cfg80211_ops - backend description for wireless configuration 3140 * struct cfg80211_ops - backend description for wireless configuration
3115 * 3141 *
3116 * This struct is registered by fullmac card drivers and/or wireless stacks 3142 * This struct is registered by fullmac card drivers and/or wireless stacks
@@ -3447,6 +3473,10 @@ struct cfg80211_pmsr_request {
3447 * Statistics should be cumulative, currently no way to reset is provided. 3473 * Statistics should be cumulative, currently no way to reset is provided.
3448 * @start_pmsr: start peer measurement (e.g. FTM) 3474 * @start_pmsr: start peer measurement (e.g. FTM)
3449 * @abort_pmsr: abort peer measurement 3475 * @abort_pmsr: abort peer measurement
3476 *
3477 * @update_owe_info: Provide updated OWE info to driver. Driver implementing SME
3478 * but offloading OWE processing to the user space will get the updated
3479 * DH IE through this interface.
3450 */ 3480 */
3451struct cfg80211_ops { 3481struct cfg80211_ops {
3452 int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); 3482 int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3761,6 +3791,8 @@ struct cfg80211_ops {
3761 struct cfg80211_pmsr_request *request); 3791 struct cfg80211_pmsr_request *request);
3762 void (*abort_pmsr)(struct wiphy *wiphy, struct wireless_dev *wdev, 3792 void (*abort_pmsr)(struct wiphy *wiphy, struct wireless_dev *wdev,
3763 struct cfg80211_pmsr_request *request); 3793 struct cfg80211_pmsr_request *request);
3794 int (*update_owe_info)(struct wiphy *wiphy, struct net_device *dev,
3795 struct cfg80211_update_owe_info *owe_info);
3764}; 3796};
3765 3797
3766/* 3798/*
@@ -7219,4 +7251,14 @@ void cfg80211_pmsr_complete(struct wireless_dev *wdev,
7219#define wiphy_WARN(wiphy, format, args...) \ 7251#define wiphy_WARN(wiphy, format, args...) \
7220 WARN(1, "wiphy: %s\n" format, wiphy_name(wiphy), ##args); 7252 WARN(1, "wiphy: %s\n" format, wiphy_name(wiphy), ##args);
7221 7253
7254/**
7255 * cfg80211_update_owe_info_event - Notify the peer's OWE info to user space
7256 * @netdev: network device
7257 * @owe_info: peer's owe info
7258 * @gfp: allocation flags
7259 */
7260void cfg80211_update_owe_info_event(struct net_device *netdev,
7261 struct cfg80211_update_owe_info *owe_info,
7262 gfp_t gfp);
7263
7222#endif /* __NET_CFG80211_H */ 7264#endif /* __NET_CFG80211_H */
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 07457f4aea00..a99d75bef598 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1065,6 +1065,11 @@
1065 * indicated by %NL80211_ATTR_WIPHY_FREQ and other attributes 1065 * indicated by %NL80211_ATTR_WIPHY_FREQ and other attributes
1066 * determining the width and type. 1066 * determining the width and type.
1067 * 1067 *
1068 * @NL80211_CMD_UPDATE_OWE_INFO: This interface allows the host driver to
1069 * offload OWE processing to user space. This intends to support
1070 * OWE AKM by the host drivers that implement SME but rely
1071 * on the user space for the cryptographic/DH IE processing in AP mode.
1072 *
1068 * @NL80211_CMD_MAX: highest used command number 1073 * @NL80211_CMD_MAX: highest used command number
1069 * @__NL80211_CMD_AFTER_LAST: internal use 1074 * @__NL80211_CMD_AFTER_LAST: internal use
1070 */ 1075 */
@@ -1285,6 +1290,8 @@ enum nl80211_commands {
1285 1290
1286 NL80211_CMD_NOTIFY_RADAR, 1291 NL80211_CMD_NOTIFY_RADAR,
1287 1292
1293 NL80211_CMD_UPDATE_OWE_INFO,
1294
1288 /* add new commands above here */ 1295 /* add new commands above here */
1289 1296
1290 /* used to define NL80211_CMD_MAX below */ 1297 /* used to define NL80211_CMD_MAX below */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 7556c0479b3c..0124bab1f8a7 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -13316,6 +13316,31 @@ nla_put_failure:
13316 return -ENOBUFS; 13316 return -ENOBUFS;
13317} 13317}
13318 13318
13319static int nl80211_update_owe_info(struct sk_buff *skb, struct genl_info *info)
13320{
13321 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13322 struct cfg80211_update_owe_info owe_info;
13323 struct net_device *dev = info->user_ptr[1];
13324
13325 if (!rdev->ops->update_owe_info)
13326 return -EOPNOTSUPP;
13327
13328 if (!info->attrs[NL80211_ATTR_STATUS_CODE] ||
13329 !info->attrs[NL80211_ATTR_MAC])
13330 return -EINVAL;
13331
13332 memset(&owe_info, 0, sizeof(owe_info));
13333 owe_info.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
13334 nla_memcpy(owe_info.peer, info->attrs[NL80211_ATTR_MAC], ETH_ALEN);
13335
13336 if (info->attrs[NL80211_ATTR_IE]) {
13337 owe_info.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
13338 owe_info.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
13339 }
13340
13341 return rdev_update_owe_info(rdev, dev, &owe_info);
13342}
13343
13319#define NL80211_FLAG_NEED_WIPHY 0x01 13344#define NL80211_FLAG_NEED_WIPHY 0x01
13320#define NL80211_FLAG_NEED_NETDEV 0x02 13345#define NL80211_FLAG_NEED_NETDEV 0x02
13321#define NL80211_FLAG_NEED_RTNL 0x04 13346#define NL80211_FLAG_NEED_RTNL 0x04
@@ -14146,6 +14171,13 @@ static const struct genl_ops nl80211_ops[] = {
14146 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | 14171 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14147 NL80211_FLAG_NEED_RTNL, 14172 NL80211_FLAG_NEED_RTNL,
14148 }, 14173 },
14174 {
14175 .cmd = NL80211_CMD_UPDATE_OWE_INFO,
14176 .doit = nl80211_update_owe_info,
14177 .flags = GENL_ADMIN_PERM,
14178 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14179 NL80211_FLAG_NEED_RTNL,
14180 },
14149}; 14181};
14150 14182
14151static struct genl_family nl80211_fam __ro_after_init = { 14183static struct genl_family nl80211_fam __ro_after_init = {
@@ -16318,6 +16350,46 @@ int cfg80211_external_auth_request(struct net_device *dev,
16318} 16350}
16319EXPORT_SYMBOL(cfg80211_external_auth_request); 16351EXPORT_SYMBOL(cfg80211_external_auth_request);
16320 16352
16353void cfg80211_update_owe_info_event(struct net_device *netdev,
16354 struct cfg80211_update_owe_info *owe_info,
16355 gfp_t gfp)
16356{
16357 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
16358 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
16359 struct sk_buff *msg;
16360 void *hdr;
16361
16362 trace_cfg80211_update_owe_info_event(wiphy, netdev, owe_info);
16363
16364 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
16365 if (!msg)
16366 return;
16367
16368 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UPDATE_OWE_INFO);
16369 if (!hdr)
16370 goto nla_put_failure;
16371
16372 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16373 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
16374 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, owe_info->peer))
16375 goto nla_put_failure;
16376
16377 if (!owe_info->ie_len ||
16378 nla_put(msg, NL80211_ATTR_IE, owe_info->ie_len, owe_info->ie))
16379 goto nla_put_failure;
16380
16381 genlmsg_end(msg, hdr);
16382
16383 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
16384 NL80211_MCGRP_MLME, gfp);
16385 return;
16386
16387nla_put_failure:
16388 genlmsg_cancel(msg, hdr);
16389 nlmsg_free(msg);
16390}
16391EXPORT_SYMBOL(cfg80211_update_owe_info_event);
16392
16321/* initialisation/exit functions */ 16393/* initialisation/exit functions */
16322 16394
16323int __init nl80211_init(void) 16395int __init nl80211_init(void)
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 5cb48d135fab..c1e3210b09e6 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -1272,4 +1272,17 @@ rdev_abort_pmsr(struct cfg80211_registered_device *rdev,
1272 trace_rdev_return_void(&rdev->wiphy); 1272 trace_rdev_return_void(&rdev->wiphy);
1273} 1273}
1274 1274
1275static inline int rdev_update_owe_info(struct cfg80211_registered_device *rdev,
1276 struct net_device *dev,
1277 struct cfg80211_update_owe_info *oweinfo)
1278{
1279 int ret = -EOPNOTSUPP;
1280
1281 trace_rdev_update_owe_info(&rdev->wiphy, dev, oweinfo);
1282 if (rdev->ops->update_owe_info)
1283 ret = rdev->ops->update_owe_info(&rdev->wiphy, dev, oweinfo);
1284 trace_rdev_return_int(&rdev->wiphy, ret);
1285 return ret;
1286}
1287
1275#endif /* __CFG80211_RDEV_OPS */ 1288#endif /* __CFG80211_RDEV_OPS */
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 44b2ce1bb13a..2dda5291fc01 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -3362,6 +3362,44 @@ TRACE_EVENT(cfg80211_pmsr_complete,
3362 WIPHY_PR_ARG, WDEV_PR_ARG, 3362 WIPHY_PR_ARG, WDEV_PR_ARG,
3363 (unsigned long long)__entry->cookie) 3363 (unsigned long long)__entry->cookie)
3364); 3364);
3365
3366TRACE_EVENT(rdev_update_owe_info,
3367 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
3368 struct cfg80211_update_owe_info *owe_info),
3369 TP_ARGS(wiphy, netdev, owe_info),
3370 TP_STRUCT__entry(WIPHY_ENTRY
3371 NETDEV_ENTRY
3372 MAC_ENTRY(peer)
3373 __field(u16, status)
3374 __dynamic_array(u8, ie, owe_info->ie_len)),
3375 TP_fast_assign(WIPHY_ASSIGN;
3376 NETDEV_ASSIGN;
3377 MAC_ASSIGN(peer, owe_info->peer);
3378 __entry->status = owe_info->status;
3379 memcpy(__get_dynamic_array(ie),
3380 owe_info->ie, owe_info->ie_len);),
3381 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT
3382 " status %d", WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer),
3383 __entry->status)
3384);
3385
3386TRACE_EVENT(cfg80211_update_owe_info_event,
3387 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
3388 struct cfg80211_update_owe_info *owe_info),
3389 TP_ARGS(wiphy, netdev, owe_info),
3390 TP_STRUCT__entry(WIPHY_ENTRY
3391 NETDEV_ENTRY
3392 MAC_ENTRY(peer)
3393 __dynamic_array(u8, ie, owe_info->ie_len)),
3394 TP_fast_assign(WIPHY_ASSIGN;
3395 NETDEV_ASSIGN;
3396 MAC_ASSIGN(peer, owe_info->peer);
3397 memcpy(__get_dynamic_array(ie), owe_info->ie,
3398 owe_info->ie_len);),
3399 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT,
3400 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer))
3401);
3402
3365#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ 3403#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
3366 3404
3367#undef TRACE_INCLUDE_PATH 3405#undef TRACE_INCLUDE_PATH