aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c3
-rw-r--r--net/mac80211/key.c21
-rw-r--r--net/mac80211/key.h3
-rw-r--r--net/wireless/nl80211.c5
-rw-r--r--net/wireless/wext-compat.c5
5 files changed, 34 insertions, 3 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 6464bfd232c9..77e9ff5ec4f3 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -141,7 +141,8 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
141 return -EINVAL; 141 return -EINVAL;
142 } 142 }
143 143
144 key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key); 144 key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key,
145 params->seq_len, params->seq);
145 if (!key) 146 if (!key)
146 return -ENOMEM; 147 return -ENOMEM;
147 148
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index b7e1350273bb..827ea8e6ee0a 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -290,9 +290,11 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
290struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, 290struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
291 int idx, 291 int idx,
292 size_t key_len, 292 size_t key_len,
293 const u8 *key_data) 293 const u8 *key_data,
294 size_t seq_len, const u8 *seq)
294{ 295{
295 struct ieee80211_key *key; 296 struct ieee80211_key *key;
297 int i, j;
296 298
297 BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS); 299 BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS);
298 300
@@ -318,14 +320,31 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
318 case ALG_TKIP: 320 case ALG_TKIP:
319 key->conf.iv_len = TKIP_IV_LEN; 321 key->conf.iv_len = TKIP_IV_LEN;
320 key->conf.icv_len = TKIP_ICV_LEN; 322 key->conf.icv_len = TKIP_ICV_LEN;
323 if (seq && seq_len == 6) {
324 for (i = 0; i < NUM_RX_DATA_QUEUES; i++) {
325 key->u.tkip.rx[i].iv32 =
326 get_unaligned_le32(&seq[2]);
327 key->u.tkip.rx[i].iv16 =
328 get_unaligned_le16(seq);
329 }
330 }
321 break; 331 break;
322 case ALG_CCMP: 332 case ALG_CCMP:
323 key->conf.iv_len = CCMP_HDR_LEN; 333 key->conf.iv_len = CCMP_HDR_LEN;
324 key->conf.icv_len = CCMP_MIC_LEN; 334 key->conf.icv_len = CCMP_MIC_LEN;
335 if (seq && seq_len == CCMP_PN_LEN) {
336 for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
337 for (j = 0; j < CCMP_PN_LEN; j++)
338 key->u.ccmp.rx_pn[i][j] =
339 seq[CCMP_PN_LEN - j - 1];
340 }
325 break; 341 break;
326 case ALG_AES_CMAC: 342 case ALG_AES_CMAC:
327 key->conf.iv_len = 0; 343 key->conf.iv_len = 0;
328 key->conf.icv_len = sizeof(struct ieee80211_mmie); 344 key->conf.icv_len = sizeof(struct ieee80211_mmie);
345 if (seq && seq_len == 6)
346 for (j = 0; j < 6; j++)
347 key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1];
329 break; 348 break;
330 } 349 }
331 memcpy(key->conf.key, key_data, key_len); 350 memcpy(key->conf.key, key_data, key_len);
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 215d3ef42a4f..9572e00f532c 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -144,7 +144,8 @@ struct ieee80211_key {
144struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, 144struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
145 int idx, 145 int idx,
146 size_t key_len, 146 size_t key_len,
147 const u8 *key_data); 147 const u8 *key_data,
148 size_t seq_len, const u8 *seq);
148/* 149/*
149 * Insert a key into data structures (sdata, sta if necessary) 150 * Insert a key into data structures (sdata, sta if necessary)
150 * to make it used, free old key. 151 * to make it used, free old key.
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index cad281390cfa..f0fec2f49828 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1115,6 +1115,11 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
1115 params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]); 1115 params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
1116 } 1116 }
1117 1117
1118 if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
1119 params.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
1120 params.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
1121 }
1122
1118 if (info->attrs[NL80211_ATTR_KEY_IDX]) 1123 if (info->attrs[NL80211_ATTR_KEY_IDX])
1119 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); 1124 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
1120 1125
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index ffc98a8d6e5c..f98090b90fbf 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -663,6 +663,11 @@ int cfg80211_wext_siwencodeext(struct net_device *dev,
663 params.key_len = ext->key_len; 663 params.key_len = ext->key_len;
664 params.cipher = cipher; 664 params.cipher = cipher;
665 665
666 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
667 params.seq = ext->rx_seq;
668 params.seq_len = 6;
669 }
670
666 return cfg80211_set_encryption( 671 return cfg80211_set_encryption(
667 rdev, dev, addr, remove, 672 rdev, dev, addr, remove,
668 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY, 673 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,