nl80211: add FILS related parameters to ROAM event
authorArend Van Spriel <arend.vanspriel@broadcom.com>
Tue, 22 May 2018 08:19:07 +0000 (10:19 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 23 May 2018 09:19:02 +0000 (11:19 +0200)
In case of FILS shared key offload the parameters can change
upon roaming of which user-space needs to be notified.

Reviewed-by: Jithu Jance <jithu.jance@broadcom.com>
Reviewed-by: Eylon Pedinovsky <eylon.pedinovsky@broadcom.com>
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/wireless/nl80211.c
net/wireless/sme.c

index 0e4a2a04d55d1ca8545d11ee180528b6b8f4981e..1e7c0df4fe333a392c32bcd06b47594d04dd988e 100644 (file)
@@ -5624,6 +5624,7 @@ cfg80211_connect_timeout(struct net_device *dev, const u8 *bssid,
  * @req_ie_len: association request IEs length
  * @resp_ie: association response IEs (may be %NULL)
  * @resp_ie_len: assoc response IEs length
+ * @fils: FILS related roaming information.
  */
 struct cfg80211_roam_info {
        struct ieee80211_channel *channel;
@@ -5633,6 +5634,7 @@ struct cfg80211_roam_info {
        size_t req_ie_len;
        const u8 *resp_ie;
        size_t resp_ie_len;
+       struct cfg80211_fils_resp_params fils;
 };
 
 /**
index 83ed1dd757e67e41338386c56040879f11fbbef7..0a412335d56bf0c7475140e8c200ffb924e087e1 100644 (file)
  * as specified in IETF RFC 6696.
  *
  * When FILS shared key authentication is completed, driver needs to provide the
- * below additional parameters to userspace.
+ * below additional parameters to userspace, which can be either after setting
+ * up a connection or after roaming.
  *     %NL80211_ATTR_FILS_KEK - used for key renewal
  *     %NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM - used in further EAP-RP exchanges
  *     %NL80211_ATTR_PMKID - used to identify the PMKSA used/generated
index 3ab443b13bb071aff902d3b543274d9cafa51fd9..ae57f9712d7d738318032febcfa419ab21d9fe12 100644 (file)
@@ -14264,7 +14264,9 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
        void *hdr;
        const u8 *bssid = info->bss ? info->bss->bssid : info->bssid;
 
-       msg = nlmsg_new(100 + info->req_ie_len + info->resp_ie_len, gfp);
+       msg = nlmsg_new(100 + info->req_ie_len + info->resp_ie_len +
+                       info->fils.kek_len + info->fils.pmk_len +
+                       (info->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp);
        if (!msg)
                return;
 
@@ -14282,7 +14284,17 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
                     info->req_ie)) ||
            (info->resp_ie &&
             nla_put(msg, NL80211_ATTR_RESP_IE, info->resp_ie_len,
-                    info->resp_ie)))
+                    info->resp_ie)) ||
+           (info->fils.update_erp_next_seq_num &&
+            nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
+                        info->fils.erp_next_seq_num)) ||
+           (info->fils.kek &&
+            nla_put(msg, NL80211_ATTR_FILS_KEK, info->fils.kek_len,
+                    info->fils.kek)) ||
+           (info->fils.pmk &&
+            nla_put(msg, NL80211_ATTR_PMK, info->fils.pmk_len, info->fils.pmk)) ||
+           (info->fils.pmkid &&
+            nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, info->fils.pmkid)))
                goto nla_put_failure;
 
        genlmsg_end(msg, hdr);
index 73881fb7f86d37ac857c95fbb57c4d039c4d696f..d536b07582f8c90e9dce435c5e569dfb8d406fe9 100644 (file)
@@ -932,6 +932,7 @@ void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info,
        struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
        struct cfg80211_event *ev;
        unsigned long flags;
+       u8 *next;
 
        if (!info->bss) {
                info->bss = cfg80211_get_bss(wdev->wiphy, info->channel,
@@ -944,19 +945,52 @@ void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info,
        if (WARN_ON(!info->bss))
                return;
 
-       ev = kzalloc(sizeof(*ev) + info->req_ie_len + info->resp_ie_len, gfp);
+       ev = kzalloc(sizeof(*ev) + info->req_ie_len + info->resp_ie_len +
+                    info->fils.kek_len + info->fils.pmk_len +
+                    (info->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp);
        if (!ev) {
                cfg80211_put_bss(wdev->wiphy, info->bss);
                return;
        }
 
        ev->type = EVENT_ROAMED;
-       ev->rm.req_ie = ((u8 *)ev) + sizeof(*ev);
-       ev->rm.req_ie_len = info->req_ie_len;
-       memcpy((void *)ev->rm.req_ie, info->req_ie, info->req_ie_len);
-       ev->rm.resp_ie = ((u8 *)ev) + sizeof(*ev) + info->req_ie_len;
-       ev->rm.resp_ie_len = info->resp_ie_len;
-       memcpy((void *)ev->rm.resp_ie, info->resp_ie, info->resp_ie_len);
+       next = ((u8 *)ev) + sizeof(*ev);
+       if (info->req_ie_len) {
+               ev->rm.req_ie = next;
+               ev->rm.req_ie_len = info->req_ie_len;
+               memcpy((void *)ev->rm.req_ie, info->req_ie, info->req_ie_len);
+               next += info->req_ie_len;
+       }
+       if (info->resp_ie_len) {
+               ev->rm.resp_ie = next;
+               ev->rm.resp_ie_len = info->resp_ie_len;
+               memcpy((void *)ev->rm.resp_ie, info->resp_ie,
+                      info->resp_ie_len);
+               next += info->resp_ie_len;
+       }
+       if (info->fils.kek_len) {
+               ev->rm.fils.kek = next;
+               ev->rm.fils.kek_len = info->fils.kek_len;
+               memcpy((void *)ev->rm.fils.kek, info->fils.kek,
+                      info->fils.kek_len);
+               next += info->fils.kek_len;
+       }
+       if (info->fils.pmk_len) {
+               ev->rm.fils.pmk = next;
+               ev->rm.fils.pmk_len = info->fils.pmk_len;
+               memcpy((void *)ev->rm.fils.pmk, info->fils.pmk,
+                      info->fils.pmk_len);
+               next += info->fils.pmk_len;
+       }
+       if (info->fils.pmkid) {
+               ev->rm.fils.pmkid = next;
+               memcpy((void *)ev->rm.fils.pmkid, info->fils.pmkid,
+                      WLAN_PMKID_LEN);
+               next += WLAN_PMKID_LEN;
+       }
+       ev->rm.fils.update_erp_next_seq_num = info->fils.update_erp_next_seq_num;
+       if (info->fils.update_erp_next_seq_num)
+               ev->rm.fils.erp_next_seq_num = info->fils.erp_next_seq_num;
        ev->rm.bss = info->bss;
 
        spin_lock_irqsave(&wdev->event_lock, flags);