summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2015-04-20 19:21:58 +0300
committerJohannes Berg <johannes.berg@intel.com>2015-05-06 14:30:00 +0300
commita31cf1c69e89e0c2d5515b04aca313f1014a714d (patch)
tree97dc2ba14c14bdfaf26624590ecd8d773a78a07a
parent9352c19f639354f093cb5457315c01bcb94aa82a (diff)
downloadlinux-a31cf1c69e89e0c2d5515b04aca313f1014a714d.tar.xz
mac80211: extend get_key() to return PN for all ciphers
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>
-rw-r--r--include/net/mac80211.h7
-rw-r--r--net/mac80211/cfg.c9
-rw-r--r--net/mac80211/key.c4
-rw-r--r--net/mac80211/key.h3
4 files changed, 19 insertions, 4 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 47b39c26fc05..67e0df14ba0f 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -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;
};
};
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index dd7014b09396..3469bbdc891c 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -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;
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 3e0b814f4db3..0a5d5c5ad30f 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -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;
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index c5a31835be0e..df430a618764 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -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;