Commit a31cf1c6 authored by Johannes Berg's avatar Johannes Berg

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: default avatarJohannes Berg <johannes.berg@intel.com>
parent 9352c19f
...@@ -1501,6 +1501,8 @@ struct ieee80211_key_conf { ...@@ -1501,6 +1501,8 @@ struct ieee80211_key_conf {
u8 key[0]; u8 key[0];
}; };
#define IEEE80211_MAX_PN_LEN 16
/** /**
* struct ieee80211_key_seq - key sequence counter * struct ieee80211_key_seq - key sequence counter
* *
...@@ -1513,6 +1515,7 @@ struct ieee80211_key_conf { ...@@ -1513,6 +1515,7 @@ struct ieee80211_key_conf {
* reverse order than in packet) * reverse order than in packet)
* @gcmp: PN data, most significant byte first (big endian, * @gcmp: PN data, most significant byte first (big endian,
* reverse order than in packet) * reverse order than in packet)
* @hw: data for HW-only (e.g. cipher scheme) keys
*/ */
struct ieee80211_key_seq { struct ieee80211_key_seq {
union { union {
...@@ -1532,6 +1535,10 @@ struct ieee80211_key_seq { ...@@ -1532,6 +1535,10 @@ struct ieee80211_key_seq {
struct { struct {
u8 pn[6]; u8 pn[6];
} gcmp; } gcmp;
struct {
u8 seq[IEEE80211_MAX_PN_LEN];
u8 seq_len;
} hw;
}; };
}; };
......
...@@ -431,6 +431,15 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, ...@@ -431,6 +431,15 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
params.seq = seq; params.seq = seq;
params.seq_len = 6; params.seq_len = 6;
break; 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; params.key = key->conf.key;
......
...@@ -485,8 +485,8 @@ ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, ...@@ -485,8 +485,8 @@ ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
break; break;
default: default:
if (cs) { if (cs) {
size_t len = (seq_len > MAX_PN_LEN) ? size_t len = (seq_len > IEEE80211_MAX_PN_LEN) ?
MAX_PN_LEN : seq_len; IEEE80211_MAX_PN_LEN : seq_len;
key->conf.iv_len = cs->hdr_len; key->conf.iv_len = cs->hdr_len;
key->conf.icv_len = cs->mic_len; key->conf.icv_len = cs->mic_len;
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#define NUM_DEFAULT_KEYS 4 #define NUM_DEFAULT_KEYS 4
#define NUM_DEFAULT_MGMT_KEYS 2 #define NUM_DEFAULT_MGMT_KEYS 2
#define MAX_PN_LEN 16
struct ieee80211_local; struct ieee80211_local;
struct ieee80211_sub_if_data; struct ieee80211_sub_if_data;
...@@ -116,7 +115,7 @@ struct ieee80211_key { ...@@ -116,7 +115,7 @@ struct ieee80211_key {
} gcmp; } gcmp;
struct { struct {
/* generic cipher scheme */ /* 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; } gen;
} u; } u;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment