wlcore: mesh: Add support for RX Broadcast Key
authorMaital Hahn <maitalm@ti.com>
Thu, 16 Jan 2020 14:33:53 +0000 (08:33 -0600)
committerKalle Valo <kvalo@codeaurora.org>
Sun, 26 Jan 2020 15:33:40 +0000 (17:33 +0200)
In order to support authentication of equals peers,
need to save RX Broadcast key per peer (on top of 1 TX broadcast key
and unicast key per peer).

Signed-off-by: Maital Hahn <maitalm@ti.com>
Acked-by: Guy Mishol <guym@ti.com>
Signed-off-by: Hari Nagalla <hnagalla@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/ti/wlcore/cmd.c
drivers/net/wireless/ti/wlcore/cmd.h
drivers/net/wireless/ti/wlcore/main.c
drivers/net/wireless/ti/wlcore/wlcore_i.h

index 2a48fc6..6ef8fc9 100644 (file)
@@ -1429,7 +1429,7 @@ out:
 int wl1271_cmd_set_ap_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                          u16 action, u8 id, u8 key_type,
                          u8 key_size, const u8 *key, u8 hlid, u32 tx_seq_32,
-                         u16 tx_seq_16)
+                         u16 tx_seq_16, bool is_pairwise)
 {
        struct wl1271_cmd_set_keys *cmd;
        int ret = 0;
@@ -1444,8 +1444,10 @@ int wl1271_cmd_set_ap_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                        lid_type = WEP_DEFAULT_LID_TYPE;
                else
                        lid_type = BROADCAST_LID_TYPE;
-       } else {
+       } else if (is_pairwise) {
                lid_type = UNICAST_LID_TYPE;
+       } else {
+               lid_type = BROADCAST_LID_TYPE;
        }
 
        wl1271_debug(DEBUG_CRYPT, "ap key action: %d id: %d lid: %d type: %d"
index 084375b..bfad7b5 100644 (file)
@@ -65,7 +65,7 @@ int wl1271_cmd_set_sta_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 int wl1271_cmd_set_ap_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                          u16 action, u8 id, u8 key_type,
                          u8 key_size, const u8 *key, u8 hlid, u32 tx_seq_32,
-                         u16 tx_seq_16);
+                         u16 tx_seq_16, bool is_pairwise);
 int wl12xx_cmd_set_peer_state(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                              u8 hlid);
 int wl12xx_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 role_id,
index e994995..ed049c9 100644 (file)
@@ -3273,7 +3273,7 @@ out:
 static int wl1271_record_ap_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                                u8 id, u8 key_type, u8 key_size,
                                const u8 *key, u8 hlid, u32 tx_seq_32,
-                               u16 tx_seq_16)
+                               u16 tx_seq_16, bool is_pairwise)
 {
        struct wl1271_ap_key *ap_key;
        int i;
@@ -3311,6 +3311,7 @@ static int wl1271_record_ap_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
        ap_key->hlid = hlid;
        ap_key->tx_seq_32 = tx_seq_32;
        ap_key->tx_seq_16 = tx_seq_16;
+       ap_key->is_pairwise = is_pairwise;
 
        wlvif->ap.recorded_keys[i] = ap_key;
        return 0;
@@ -3346,7 +3347,7 @@ static int wl1271_ap_init_hwenc(struct wl1271 *wl, struct wl12xx_vif *wlvif)
                                            key->id, key->key_type,
                                            key->key_size, key->key,
                                            hlid, key->tx_seq_32,
-                                           key->tx_seq_16);
+                                           key->tx_seq_16, key->is_pairwise);
                if (ret < 0)
                        goto out;
 
@@ -3369,7 +3370,8 @@ out:
 static int wl1271_set_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                       u16 action, u8 id, u8 key_type,
                       u8 key_size, const u8 *key, u32 tx_seq_32,
-                      u16 tx_seq_16, struct ieee80211_sta *sta)
+                      u16 tx_seq_16, struct ieee80211_sta *sta,
+                      bool is_pairwise)
 {
        int ret;
        bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
@@ -3396,12 +3398,12 @@ static int wl1271_set_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                        ret = wl1271_record_ap_key(wl, wlvif, id,
                                             key_type, key_size,
                                             key, hlid, tx_seq_32,
-                                            tx_seq_16);
+                                            tx_seq_16, is_pairwise);
                } else {
                        ret = wl1271_cmd_set_ap_key(wl, wlvif, action,
                                             id, key_type, key_size,
                                             key, hlid, tx_seq_32,
-                                            tx_seq_16);
+                                            tx_seq_16, is_pairwise);
                }
 
                if (ret < 0)
@@ -3501,6 +3503,7 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
        u16 tx_seq_16 = 0;
        u8 key_type;
        u8 hlid;
+       bool is_pairwise;
 
        wl1271_debug(DEBUG_MAC80211, "mac80211 set key");
 
@@ -3550,12 +3553,14 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
                return -EOPNOTSUPP;
        }
 
+       is_pairwise = key_conf->flags & IEEE80211_KEY_FLAG_PAIRWISE;
+
        switch (cmd) {
        case SET_KEY:
                ret = wl1271_set_key(wl, wlvif, KEY_ADD_OR_REPLACE,
                                 key_conf->keyidx, key_type,
                                 key_conf->keylen, key_conf->key,
-                                tx_seq_32, tx_seq_16, sta);
+                                tx_seq_32, tx_seq_16, sta, is_pairwise);
                if (ret < 0) {
                        wl1271_error("Could not add or replace key");
                        return ret;
@@ -3581,7 +3586,7 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
                ret = wl1271_set_key(wl, wlvif, KEY_REMOVE,
                                     key_conf->keyidx, key_type,
                                     key_conf->keylen, key_conf->key,
-                                    0, 0, sta);
+                                    0, 0, sta, is_pairwise);
                if (ret < 0) {
                        wl1271_error("Could not remove key");
                        return ret;
@@ -6223,6 +6228,7 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
 
        ieee80211_hw_set(wl->hw, SUPPORT_FAST_XMIT);
        ieee80211_hw_set(wl->hw, CHANCTX_STA_CSA);
+       ieee80211_hw_set(wl->hw, SUPPORTS_PER_STA_GTK);
        ieee80211_hw_set(wl->hw, QUEUE_CONTROL);
        ieee80211_hw_set(wl->hw, TX_AMPDU_SETUP_IN_HW);
        ieee80211_hw_set(wl->hw, AMPDU_AGGREGATION);
@@ -6267,7 +6273,8 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
 
        wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD |
                                WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
-                               WIPHY_FLAG_HAS_CHANNEL_SWITCH;
+                               WIPHY_FLAG_HAS_CHANNEL_SWITCH |
++                              WIPHY_FLAG_IBSS_RSN;
 
        wl->hw->wiphy->features |= NL80211_FEATURE_AP_SCAN;
 
index 6fab60b..eefae3f 100644 (file)
@@ -212,6 +212,7 @@ struct wl1271_ap_key {
        u8 hlid;
        u32 tx_seq_32;
        u16 tx_seq_16;
+       bool is_pairwise;
 };
 
 enum wl12xx_flags {