rsi: security enhancements for AP mode
authorPrameela Rani Garnepudi <prameela.j04cs@gmail.com>
Wed, 16 Aug 2017 13:13:18 +0000 (18:43 +0530)
committerKalle Valo <kvalo@codeaurora.org>
Thu, 17 Aug 2017 07:07:00 +0000 (10:07 +0300)
Station id should be set in load key frame configured to device.
For WEP mode, key is configured once from mac80211. This key is
saved and configured to device every time a station is connected.

Signed-off-by: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/rsi/rsi_91x_mac80211.c
drivers/net/wireless/rsi/rsi_91x_mgmt.c
drivers/net/wireless/rsi/rsi_main.h
drivers/net/wireless/rsi/rsi_mgmt.h

index f2cb61f2b2683fcc3f7191c007eac74ac4203b6a..8b983d03f2da49e8d2cef8173f221997e31cdd30 100644 (file)
@@ -758,11 +758,14 @@ static int rsi_mac80211_conf_tx(struct ieee80211_hw *hw,
  */
 static int rsi_hal_key_config(struct ieee80211_hw *hw,
                              struct ieee80211_vif *vif,
-                             struct ieee80211_key_conf *key)
+                             struct ieee80211_key_conf *key,
+                             struct ieee80211_sta *sta)
 {
        struct rsi_hw *adapter = hw->priv;
+       struct rsi_sta *rsta = NULL;
        int status;
        u8 key_type;
+       s16 sta_id = 0;
 
        if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
                key_type = RSI_PAIRWISE_KEY;
@@ -772,23 +775,35 @@ static int rsi_hal_key_config(struct ieee80211_hw *hw,
        rsi_dbg(ERR_ZONE, "%s: Cipher 0x%x key_type: %d key_len: %d\n",
                __func__, key->cipher, key_type, key->keylen);
 
-       if ((key->cipher == WLAN_CIPHER_SUITE_WEP104) ||
-           (key->cipher == WLAN_CIPHER_SUITE_WEP40)) {
-               status = rsi_hal_load_key(adapter->priv,
-                                         key->key,
-                                         key->keylen,
-                                         RSI_PAIRWISE_KEY,
-                                         key->keyidx,
-                                         key->cipher);
-               if (status)
-                       return status;
+       if (vif->type == NL80211_IFTYPE_AP) {
+               if (sta) {
+                       rsta = rsi_find_sta(adapter->priv, sta->addr);
+                       if (rsta)
+                               sta_id = rsta->sta_id;
+               }
+               adapter->priv->key = key;
+       } else {
+               if ((key->cipher == WLAN_CIPHER_SUITE_WEP104) ||
+                   (key->cipher == WLAN_CIPHER_SUITE_WEP40)) {
+                       status = rsi_hal_load_key(adapter->priv,
+                                                 key->key,
+                                                 key->keylen,
+                                                 RSI_PAIRWISE_KEY,
+                                                 key->keyidx,
+                                                 key->cipher,
+                                                 sta_id);
+                       if (status)
+                               return status;
+               }
        }
+
        return rsi_hal_load_key(adapter->priv,
                                key->key,
                                key->keylen,
                                key_type,
                                key->keyidx,
-                               key->cipher);
+                               key->cipher,
+                               sta_id);
 }
 
 /**
@@ -816,7 +831,7 @@ static int rsi_mac80211_set_key(struct ieee80211_hw *hw,
        switch (cmd) {
        case SET_KEY:
                secinfo->security_enable = true;
-               status = rsi_hal_key_config(hw, vif, key);
+               status = rsi_hal_key_config(hw, vif, key, sta);
                if (status) {
                        mutex_unlock(&common->mutex);
                        return status;
@@ -834,10 +849,11 @@ static int rsi_mac80211_set_key(struct ieee80211_hw *hw,
                break;
 
        case DISABLE_KEY:
-               secinfo->security_enable = false;
+               if (vif->type == NL80211_IFTYPE_STATION)
+                       secinfo->security_enable = false;
                rsi_dbg(ERR_ZONE, "%s: RSI del key\n", __func__);
                memset(key, 0, sizeof(struct ieee80211_key_conf));
-               status = rsi_hal_key_config(hw, vif, key);
+               status = rsi_hal_key_config(hw, vif, key, sta);
                break;
 
        default:
@@ -1242,6 +1258,20 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
                        rsi_inform_bss_status(common, AP_OPMODE, 1, sta->addr,
                                              sta->wme, sta->aid, sta, sta_idx);
 
+                       if (common->key) {
+                               struct ieee80211_key_conf *key = common->key;
+
+                               if ((key->cipher == WLAN_CIPHER_SUITE_WEP104) ||
+                                   (key->cipher == WLAN_CIPHER_SUITE_WEP40))
+                                       rsi_hal_load_key(adapter->priv,
+                                                        key->key,
+                                                        key->keylen,
+                                                        RSI_PAIRWISE_KEY,
+                                                        key->keyidx,
+                                                        key->cipher,
+                                                        sta_idx);
+                       }
+
                        common->num_stations++;
                }
        }
index 2d3cae561be2ad0bed7277d37f6b9a30b86f551a..f7b550f900c4f63145135b5d0d213058dd9b3c85 100644 (file)
@@ -715,8 +715,10 @@ int rsi_hal_load_key(struct rsi_common *common,
                     u16 key_len,
                     u8 key_type,
                     u8 key_id,
-                    u32 cipher)
+                    u32 cipher,
+                    s16 sta_id)
 {
+       struct ieee80211_vif *vif = common->priv->vifs[0];
        struct sk_buff *skb = NULL;
        struct rsi_set_key *set_key;
        u16 key_descriptor = 0;
@@ -734,8 +736,11 @@ int rsi_hal_load_key(struct rsi_common *common,
        memset(skb->data, 0, frame_len);
        set_key = (struct rsi_set_key *)skb->data;
 
-       if (key_type == RSI_GROUP_KEY)
+       if (key_type == RSI_GROUP_KEY) {
                key_descriptor = RSI_KEY_TYPE_BROADCAST;
+               if (vif->type == NL80211_IFTYPE_AP)
+                       key_descriptor |= RSI_KEY_MODE_AP;
+       }
        if ((cipher == WLAN_CIPHER_SUITE_WEP40) ||
            (cipher == WLAN_CIPHER_SUITE_WEP104)) {
                key_id = 0;
@@ -754,6 +759,7 @@ int rsi_hal_load_key(struct rsi_common *common,
                        (frame_len - FRAME_DESC_SZ), RSI_WIFI_MGMT_Q);
        set_key->desc_dword0.frame_type = SET_KEY_REQ;
        set_key->key_desc = cpu_to_le16(key_descriptor);
+       set_key->sta_id = sta_id;
 
        if (data) {
                if ((cipher == WLAN_CIPHER_SUITE_WEP40) ||
index 169e2f9e3c5e5035f5993c7ff76ffd802241e7da..2c18dde633ea39c557a02ce7c954fe104b4fa1a6 100644 (file)
@@ -269,6 +269,7 @@ struct rsi_common {
        struct rsi_sta stations[RSI_MAX_ASSOC_STAS + 1];
        int num_stations;
        int max_stations;
+       struct ieee80211_key_conf *key;
 };
 
 enum host_intf {
index 2d827330130dc427467a326f9e919ffdc6168f7c..c6e1fa669a27784444eee2b99c3676336003d8c8 100644 (file)
@@ -409,6 +409,7 @@ struct rsi_dynamic_s {
 #define RSI_WEP_KEY_104                BIT(3)
 #define RSI_CIPHER_WPA         BIT(4)
 #define RSI_CIPHER_TKIP                BIT(5)
+#define RSI_KEY_MODE_AP                BIT(7)
 #define RSI_PROTECT_DATA_FRAMES        BIT(13)
 #define RSI_KEY_ID_MASK                0xC0
 #define RSI_KEY_ID_OFFSET      14
@@ -612,7 +613,7 @@ int rsi_send_aggregation_params_frame(struct rsi_common *common, u16 tid,
                                      u16 ssn, u8 buf_size, u8 event,
                                      u8 sta_id);
 int rsi_hal_load_key(struct rsi_common *common, u8 *data, u16 key_len,
-                    u8 key_type, u8 key_id, u32 cipher);
+                    u8 key_type, u8 key_id, u32 cipher, s16 sta_id);
 int rsi_set_channel(struct rsi_common *common,
                    struct ieee80211_channel *channel);
 int rsi_send_vap_dynamic_update(struct rsi_common *common);