diff options
Diffstat (limited to 'net/mac80211/key.c')
-rw-r--r-- | net/mac80211/key.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index b7e1350273b..827ea8e6ee0 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, | |||
290 | struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, | 290 | struct 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); |