mac80211: extend get_key() to return PN for all ciphers
authorJohannes Berg <johannes.berg@intel.com>
Mon, 20 Apr 2015 16:21:58 +0000 (18:21 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 6 May 2015 11:30:00 +0000 (13:30 +0200)
For ciphers not supported by mac80211, the function currently
doesn't return any PN data. Fix this by extending the driver's
get_key_seq() a little more to allow moving arbitrary PN data.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/mac80211.h
net/mac80211/cfg.c
net/mac80211/key.c
net/mac80211/key.h

index 47b39c26fc058fe24c16e442b8f1f25a411e0fa6..67e0df14ba0fd1c5b76729908c62104fdbe0496b 100644 (file)
@@ -1501,6 +1501,8 @@ struct ieee80211_key_conf {
        u8 key[0];
 };
 
+#define IEEE80211_MAX_PN_LEN   16
+
 /**
  * struct ieee80211_key_seq - key sequence counter
  *
@@ -1513,6 +1515,7 @@ struct ieee80211_key_conf {
  *     reverse order than in packet)
  * @gcmp: PN data, most significant byte first (big endian,
  *     reverse order than in packet)
+ * @hw: data for HW-only (e.g. cipher scheme) keys
  */
 struct ieee80211_key_seq {
        union {
@@ -1532,6 +1535,10 @@ struct ieee80211_key_seq {
                struct {
                        u8 pn[6];
                } gcmp;
+               struct {
+                       u8 seq[IEEE80211_MAX_PN_LEN];
+                       u8 seq_len;
+               } hw;
        };
 };
 
index dd7014b093963c1f19ced327e4fc92ad932f323e..3469bbdc891c35afe10017fe4d9450c29955a1f0 100644 (file)
@@ -431,6 +431,15 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
                params.seq = seq;
                params.seq_len = 6;
                break;
+       default:
+               if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
+                       break;
+               if (WARN_ON(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))
+                       break;
+               drv_get_key_seq(sdata->local, key, &kseq);
+               params.seq = kseq.hw.seq;
+               params.seq_len = kseq.hw.seq_len;
+               break;
        }
 
        params.key = key->conf.key;
index 3e0b814f4db3d27828dff5fd38af17987447b6bf..0a5d5c5ad30fc8eb32ccb99d4380691c163f0ae8 100644 (file)
@@ -485,8 +485,8 @@ ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
                break;
        default:
                if (cs) {
-                       size_t len = (seq_len > MAX_PN_LEN) ?
-                                               MAX_PN_LEN : seq_len;
+                       size_t len = (seq_len > IEEE80211_MAX_PN_LEN) ?
+                                               IEEE80211_MAX_PN_LEN : seq_len;
 
                        key->conf.iv_len = cs->hdr_len;
                        key->conf.icv_len = cs->mic_len;
index c5a31835be0e0ca22c154b1345d91be761308833..df430a6187649cbebe38bf1909f81a3ac90677a7 100644 (file)
@@ -18,7 +18,6 @@
 
 #define NUM_DEFAULT_KEYS 4
 #define NUM_DEFAULT_MGMT_KEYS 2
-#define MAX_PN_LEN 16
 
 struct ieee80211_local;
 struct ieee80211_sub_if_data;
@@ -116,7 +115,7 @@ struct ieee80211_key {
                } gcmp;
                struct {
                        /* generic cipher scheme */
-                       u8 rx_pn[IEEE80211_NUM_TIDS + 1][MAX_PN_LEN];
+                       u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_MAX_PN_LEN];
                } gen;
        } u;