Skip to content

Commit

Permalink
cfg80211/nl80211: Offload OWE processing to user space
Browse files Browse the repository at this point in the history
This interface allows the host driver to offload OWE processing to
user space. This intends to support OWE/Enhanced Open AKM by the host
drivers that implement SME but rely on the user space for
the crypotographic/OWE processing.Such drivers are not capable of
processing/deriving the DH IE's.

This interface acts as both the event from the driver to userspace
and a command from userspace to the driver.

Host driver shall use the event to notify the OWE info of the peer
to the userspace for the cryptographic processing of the DH ie's.
Accordingly, the userspace shall update the OWE info/DH ie's to
the host driver corresponding to the peer.

Above sequence aims for the AP mode where the event carries the
OWE info of the peer(STA) obtained in the Assoc Request.
The request interface from the userspace shall update the OWE
info to the host driver, which is used to send the Assoc response
to the peer.

This OWE info in the command interface shall contain the ie's which
either include the pmkid of the peer if the PMKSA is still valid or
an updated DH ie's for generating a new PMKSA with the peer.

Change-Id: Id5a2e800bdae1ea31a20a062d012cc33e5a3c6a3
CRs-Fixed: 2414077
Signed-off-by: Liangwei Dong <liangwei@codeaurora.org>
Signed-off-by: Sunil Dutt <usdutt@codeaurora.org>
  • Loading branch information
Sunil Dutt authored and codeworkx committed Oct 5, 2019
1 parent 3237e6c commit 64b33e7
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 0 deletions.
41 changes: 41 additions & 0 deletions include/net/cfg80211.h
Expand Up @@ -2426,6 +2426,31 @@ struct cfg80211_external_auth_params {
const u8 *pmkid;
};

/**
* struct cfg80211_update_owe_info - OWE Information
*
* This structure provides information needed for the drivers to offload OWE
* (Oppurtunistic Wireless Encryption) processing to the user space.
*
* Commonly used across update_owe request and event interfaces.
*
* @bssid: BSSID of the peer from which the OWE processing has to be done.
* @status: status code, %WLAN_STATUS_SUCCESS for successful OWE info
* processing, use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space
* cannot give you the real status code for failures. Used only for
* OWE update response command interface (user space to driver).
* @ie: IE's obtained from the peer or constructed by the user space. These are
* the IE's of the remote peer in the event from the host driver and
* the constructed IE's by the user space in the request interface.
* @ie_len: Length of IE's in octets.
*/
struct cfg80211_update_owe_info {
u8 bssid[ETH_ALEN] __aligned(2);
u16 status;
const u8 *ie;
size_t ie_len;
};

/**
* struct cfg80211_ops - backend description for wireless configuration
*
Expand Down Expand Up @@ -2724,6 +2749,10 @@ struct cfg80211_external_auth_params {
*
* @external_auth: indicates result of offloaded authentication processing from
* user space
*
* @update_owe_info: Provide updated OWE info to driver. Driver implementing SME
* but offloading the OWE processing to the user space will get the updated
* DH IE's (from the IE's) obtained through this interface.
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
Expand Down Expand Up @@ -2995,6 +3024,8 @@ struct cfg80211_ops {
const u8 *addr);
int (*external_auth)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_external_auth_params *params);
int (*update_owe_info)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_update_owe_info *owe_info);
};

/*
Expand Down Expand Up @@ -5886,4 +5917,14 @@ int cfg80211_external_auth_request(struct net_device *netdev,
*/
#define CFG80211_REMOVE_IEEE80211_BACKPORT 1

/**
* cfg80211_update_owe_info_event - Notify the peer's OWE info to user space
* @netdev: network device
* @owe_info: peer's owe info
* @gfp: allocation flags
*/
void cfg80211_update_owe_info_event(struct net_device *netdev,
struct cfg80211_update_owe_info *owe_info,
gfp_t gfp);

#endif /* __NET_CFG80211_H */
6 changes: 6 additions & 0 deletions include/uapi/linux/nl80211.h
Expand Up @@ -990,6 +990,11 @@
* indicated by %NL80211_ATTR_WIPHY_FREQ and other attributes
* determining the width and type.
*
* @NL80211_CMD_UPDATE_OWE_INFO: This interface allows the host driver to
* offload OWE processing to user space. This intends to support
* OWE/Enhanced Open AKM by the host drivers that implemnt SME but rely
* on the user space for the crypotographic/DH IE processing.
*
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
Expand Down Expand Up @@ -1210,6 +1215,7 @@ enum nl80211_commands {

NL80211_CMD_NOTIFY_RADAR,

NL80211_CMD_UPDATE_OWE_INFO,
/* add new commands above here */

/* used to define NL80211_CMD_MAX below */
Expand Down
79 changes: 79 additions & 0 deletions net/wireless/nl80211.c
Expand Up @@ -11212,6 +11212,34 @@ static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
return rdev_external_auth(rdev, dev, &params);
}

static int nl80211_update_owe_info(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct cfg80211_update_owe_info owe_info;
struct net_device *dev = info->user_ptr[1];

if (!rdev->ops->update_owe_info)
return -EOPNOTSUPP;

if (!info->attrs[NL80211_ATTR_STATUS_CODE] ||
(info->attrs[NL80211_ATTR_IE] &&
!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])))
return -EINVAL;

memset(&owe_info, 0, sizeof(owe_info));
owe_info.status =
nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
if (info->attrs[NL80211_ATTR_MAC])
nla_memcpy(owe_info.bssid, info->attrs[NL80211_ATTR_MAC],
ETH_ALEN);
if (info->attrs[NL80211_ATTR_IE]) {
owe_info.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
owe_info.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
}

return rdev_update_owe_info(rdev, dev, &owe_info);
}

#define NL80211_FLAG_NEED_WIPHY 0x01
#define NL80211_FLAG_NEED_NETDEV 0x02
#define NL80211_FLAG_NEED_RTNL 0x04
Expand Down Expand Up @@ -12054,6 +12082,14 @@ static const struct genl_ops nl80211_ops[] = {
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_UPDATE_OWE_INFO,
.doit = nl80211_update_owe_info,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
};

/* notification functions */
Expand Down Expand Up @@ -14048,6 +14084,49 @@ int cfg80211_external_auth_request(struct net_device *dev,
}
EXPORT_SYMBOL(cfg80211_external_auth_request);

void cfg80211_update_owe_info_event(struct net_device *netdev,
struct cfg80211_update_owe_info *owe_info,
gfp_t gfp)
{
struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
struct sk_buff *msg;
void *hdr;

trace_cfg80211_update_owe_info_event(wiphy, netdev, owe_info);

if (!owe_info)
return;

msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
if (!msg)
return;

hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UPDATE_OWE_INFO);
if (!hdr)
goto nla_put_failure;

if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, owe_info->bssid))
goto nla_put_failure;

if (nla_put(msg, NL80211_ATTR_IE, owe_info->ie_len, owe_info->ie))
goto nla_put_failure;

genlmsg_end(msg, hdr);

genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
NL80211_MCGRP_MLME, gfp);
return;

nla_put_failure:
if (hdr)
genlmsg_cancel(msg, hdr);
nlmsg_free(msg);
}
EXPORT_SYMBOL(cfg80211_update_owe_info_event);

/* initialisation/exit functions */

int nl80211_init(void)
Expand Down
12 changes: 12 additions & 0 deletions net/wireless/rdev-ops.h
Expand Up @@ -1054,4 +1054,16 @@ rdev_external_auth(struct cfg80211_registered_device *rdev,
return ret;
}

static inline int rdev_update_owe_info(struct cfg80211_registered_device *rdev,
struct net_device *dev,
struct cfg80211_update_owe_info *oweinfo)
{
int ret;

trace_rdev_update_owe_info(&rdev->wiphy, dev, oweinfo);
ret = rdev->ops->update_owe_info(&rdev->wiphy, dev, oweinfo);
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
}

#endif /* __CFG80211_RDEV_OPS */
37 changes: 37 additions & 0 deletions net/wireless/trace.h
Expand Up @@ -2866,6 +2866,43 @@ TRACE_EVENT(cfg80211_stop_iface,
WIPHY_PR_ARG, WDEV_PR_ARG)
);

TRACE_EVENT(rdev_update_owe_info,
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
struct cfg80211_update_owe_info *owe_info),
TP_ARGS(wiphy, netdev, owe_info),
TP_STRUCT__entry(WIPHY_ENTRY
NETDEV_ENTRY
MAC_ENTRY(bssid)
__field(u16, status)
__dynamic_array(u8, ie, owe_info->ie_len)),
TP_fast_assign(WIPHY_ASSIGN;
NETDEV_ASSIGN;
MAC_ASSIGN(bssid, owe_info->bssid);
__entry->status = owe_info->status;
memcpy(__get_dynamic_array(ie),
owe_info->ie, owe_info->ie_len);),
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT
" status %d", WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid),
__entry->status)
);

TRACE_EVENT(cfg80211_update_owe_info_event,
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
struct cfg80211_update_owe_info *owe_info),
TP_ARGS(wiphy, netdev, owe_info),
TP_STRUCT__entry(WIPHY_ENTRY
NETDEV_ENTRY
MAC_ENTRY(bssid)
__dynamic_array(u8, ie, owe_info->ie_len)),
TP_fast_assign(WIPHY_ASSIGN;
NETDEV_ASSIGN;
MAC_ASSIGN(bssid, owe_info->bssid);
memcpy(__get_dynamic_array(ie), owe_info->ie,
owe_info->ie_len);),
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT,
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid))
);

#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */

#undef TRACE_INCLUDE_PATH
Expand Down

0 comments on commit 64b33e7

Please sign in to comment.