]> git.karo-electronics.de Git - mv-sheeva.git/blob - net/mac80211/key.c
mac80211: dont program keys for stations not uploaded
[mv-sheeva.git] / net / mac80211 / key.c
1 /*
2  * Copyright 2002-2005, Instant802 Networks, Inc.
3  * Copyright 2005-2006, Devicescape Software, Inc.
4  * Copyright 2006-2007  Jiri Benc <jbenc@suse.cz>
5  * Copyright 2007-2008  Johannes Berg <johannes@sipsolutions.net>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11
12 #include <linux/if_ether.h>
13 #include <linux/etherdevice.h>
14 #include <linux/list.h>
15 #include <linux/rcupdate.h>
16 #include <linux/rtnetlink.h>
17 #include <linux/slab.h>
18 #include <linux/export.h>
19 #include <net/mac80211.h>
20 #include "ieee80211_i.h"
21 #include "driver-ops.h"
22 #include "debugfs_key.h"
23 #include "aes_ccm.h"
24 #include "aes_cmac.h"
25
26
27 /**
28  * DOC: Key handling basics
29  *
30  * Key handling in mac80211 is done based on per-interface (sub_if_data)
31  * keys and per-station keys. Since each station belongs to an interface,
32  * each station key also belongs to that interface.
33  *
34  * Hardware acceleration is done on a best-effort basis for algorithms
35  * that are implemented in software,  for each key the hardware is asked
36  * to enable that key for offloading but if it cannot do that the key is
37  * simply kept for software encryption (unless it is for an algorithm
38  * that isn't implemented in software).
39  * There is currently no way of knowing whether a key is handled in SW
40  * or HW except by looking into debugfs.
41  *
42  * All key management is internally protected by a mutex. Within all
43  * other parts of mac80211, key references are, just as STA structure
44  * references, protected by RCU. Note, however, that some things are
45  * unprotected, namely the key->sta dereferences within the hardware
46  * acceleration functions. This means that sta_info_destroy() must
47  * remove the key which waits for an RCU grace period.
48  */
49
50 static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
51
52 static void assert_key_lock(struct ieee80211_local *local)
53 {
54         lockdep_assert_held(&local->key_mtx);
55 }
56
57 static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
58 {
59         /*
60          * When this count is zero, SKB resizing for allocating tailroom
61          * for IV or MMIC is skipped. But, this check has created two race
62          * cases in xmit path while transiting from zero count to one:
63          *
64          * 1. SKB resize was skipped because no key was added but just before
65          * the xmit key is added and SW encryption kicks off.
66          *
67          * 2. SKB resize was skipped because all the keys were hw planted but
68          * just before xmit one of the key is deleted and SW encryption kicks
69          * off.
70          *
71          * In both the above case SW encryption will find not enough space for
72          * tailroom and exits with WARN_ON. (See WARN_ONs at wpa.c)
73          *
74          * Solution has been explained at
75          * http://mid.gmane.org/1308590980.4322.19.camel@jlt3.sipsolutions.net
76          */
77
78         if (!sdata->crypto_tx_tailroom_needed_cnt++) {
79                 /*
80                  * Flush all XMIT packets currently using HW encryption or no
81                  * encryption at all if the count transition is from 0 -> 1.
82                  */
83                 synchronize_net();
84         }
85 }
86
87 static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
88 {
89         struct ieee80211_sub_if_data *sdata;
90         struct sta_info *sta;
91         int ret;
92
93         might_sleep();
94
95         if (!key->local->ops->set_key)
96                 goto out_unsupported;
97
98         assert_key_lock(key->local);
99
100         sta = key->sta;
101
102         /*
103          * If this is a per-STA GTK, check if it
104          * is supported; if not, return.
105          */
106         if (sta && !(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE) &&
107             !(key->local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK))
108                 goto out_unsupported;
109
110         if (sta && !sta->uploaded)
111                 goto out_unsupported;
112
113         sdata = key->sdata;
114         if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
115                 /*
116                  * The driver doesn't know anything about VLAN interfaces.
117                  * Hence, don't send GTKs for VLAN interfaces to the driver.
118                  */
119                 if (!(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE))
120                         goto out_unsupported;
121         }
122
123         ret = drv_set_key(key->local, SET_KEY, sdata,
124                           sta ? &sta->sta : NULL, &key->conf);
125
126         if (!ret) {
127                 key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
128
129                 if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
130                       (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
131                       (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
132                         sdata->crypto_tx_tailroom_needed_cnt--;
133
134                 WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
135                         (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV));
136
137                 return 0;
138         }
139
140         if (ret != -ENOSPC && ret != -EOPNOTSUPP)
141                 wiphy_err(key->local->hw.wiphy,
142                           "failed to set key (%d, %pM) to hardware (%d)\n",
143                           key->conf.keyidx,
144                           sta ? sta->sta.addr : bcast_addr, ret);
145
146  out_unsupported:
147         switch (key->conf.cipher) {
148         case WLAN_CIPHER_SUITE_WEP40:
149         case WLAN_CIPHER_SUITE_WEP104:
150         case WLAN_CIPHER_SUITE_TKIP:
151         case WLAN_CIPHER_SUITE_CCMP:
152         case WLAN_CIPHER_SUITE_AES_CMAC:
153                 /* all of these we can do in software */
154                 return 0;
155         default:
156                 return -EINVAL;
157         }
158 }
159
160 static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
161 {
162         struct ieee80211_sub_if_data *sdata;
163         struct sta_info *sta;
164         int ret;
165
166         might_sleep();
167
168         if (!key || !key->local->ops->set_key)
169                 return;
170
171         assert_key_lock(key->local);
172
173         if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
174                 return;
175
176         sta = key->sta;
177         sdata = key->sdata;
178
179         if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
180               (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
181               (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
182                 increment_tailroom_need_count(sdata);
183
184         ret = drv_set_key(key->local, DISABLE_KEY, sdata,
185                           sta ? &sta->sta : NULL, &key->conf);
186
187         if (ret)
188                 wiphy_err(key->local->hw.wiphy,
189                           "failed to remove key (%d, %pM) from hardware (%d)\n",
190                           key->conf.keyidx,
191                           sta ? sta->sta.addr : bcast_addr, ret);
192
193         key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
194 }
195
196 void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
197 {
198         struct ieee80211_key *key;
199
200         key = container_of(key_conf, struct ieee80211_key, conf);
201
202         might_sleep();
203         assert_key_lock(key->local);
204
205         key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
206
207         /*
208          * Flush TX path to avoid attempts to use this key
209          * after this function returns. Until then, drivers
210          * must be prepared to handle the key.
211          */
212         synchronize_rcu();
213 }
214 EXPORT_SYMBOL_GPL(ieee80211_key_removed);
215
216 static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
217                                         int idx, bool uni, bool multi)
218 {
219         struct ieee80211_key *key = NULL;
220
221         assert_key_lock(sdata->local);
222
223         if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
224                 key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
225
226         if (uni)
227                 rcu_assign_pointer(sdata->default_unicast_key, key);
228         if (multi)
229                 rcu_assign_pointer(sdata->default_multicast_key, key);
230
231         ieee80211_debugfs_key_update_default(sdata);
232 }
233
234 void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
235                                bool uni, bool multi)
236 {
237         mutex_lock(&sdata->local->key_mtx);
238         __ieee80211_set_default_key(sdata, idx, uni, multi);
239         mutex_unlock(&sdata->local->key_mtx);
240 }
241
242 static void
243 __ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx)
244 {
245         struct ieee80211_key *key = NULL;
246
247         assert_key_lock(sdata->local);
248
249         if (idx >= NUM_DEFAULT_KEYS &&
250             idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
251                 key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
252
253         rcu_assign_pointer(sdata->default_mgmt_key, key);
254
255         ieee80211_debugfs_key_update_default(sdata);
256 }
257
258 void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
259                                     int idx)
260 {
261         mutex_lock(&sdata->local->key_mtx);
262         __ieee80211_set_default_mgmt_key(sdata, idx);
263         mutex_unlock(&sdata->local->key_mtx);
264 }
265
266
267 static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
268                                     struct sta_info *sta,
269                                     bool pairwise,
270                                     struct ieee80211_key *old,
271                                     struct ieee80211_key *new)
272 {
273         int idx;
274         bool defunikey, defmultikey, defmgmtkey;
275
276         if (new)
277                 list_add_tail(&new->list, &sdata->key_list);
278
279         if (sta && pairwise) {
280                 rcu_assign_pointer(sta->ptk, new);
281         } else if (sta) {
282                 if (old)
283                         idx = old->conf.keyidx;
284                 else
285                         idx = new->conf.keyidx;
286                 rcu_assign_pointer(sta->gtk[idx], new);
287         } else {
288                 WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx);
289
290                 if (old)
291                         idx = old->conf.keyidx;
292                 else
293                         idx = new->conf.keyidx;
294
295                 defunikey = old &&
296                         old == key_mtx_dereference(sdata->local,
297                                                 sdata->default_unicast_key);
298                 defmultikey = old &&
299                         old == key_mtx_dereference(sdata->local,
300                                                 sdata->default_multicast_key);
301                 defmgmtkey = old &&
302                         old == key_mtx_dereference(sdata->local,
303                                                 sdata->default_mgmt_key);
304
305                 if (defunikey && !new)
306                         __ieee80211_set_default_key(sdata, -1, true, false);
307                 if (defmultikey && !new)
308                         __ieee80211_set_default_key(sdata, -1, false, true);
309                 if (defmgmtkey && !new)
310                         __ieee80211_set_default_mgmt_key(sdata, -1);
311
312                 rcu_assign_pointer(sdata->keys[idx], new);
313                 if (defunikey && new)
314                         __ieee80211_set_default_key(sdata, new->conf.keyidx,
315                                                     true, false);
316                 if (defmultikey && new)
317                         __ieee80211_set_default_key(sdata, new->conf.keyidx,
318                                                     false, true);
319                 if (defmgmtkey && new)
320                         __ieee80211_set_default_mgmt_key(sdata,
321                                                          new->conf.keyidx);
322         }
323
324         if (old)
325                 list_del(&old->list);
326 }
327
328 struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
329                                           const u8 *key_data,
330                                           size_t seq_len, const u8 *seq)
331 {
332         struct ieee80211_key *key;
333         int i, j, err;
334
335         BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS);
336
337         key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL);
338         if (!key)
339                 return ERR_PTR(-ENOMEM);
340
341         /*
342          * Default to software encryption; we'll later upload the
343          * key to the hardware if possible.
344          */
345         key->conf.flags = 0;
346         key->flags = 0;
347
348         key->conf.cipher = cipher;
349         key->conf.keyidx = idx;
350         key->conf.keylen = key_len;
351         switch (cipher) {
352         case WLAN_CIPHER_SUITE_WEP40:
353         case WLAN_CIPHER_SUITE_WEP104:
354                 key->conf.iv_len = WEP_IV_LEN;
355                 key->conf.icv_len = WEP_ICV_LEN;
356                 break;
357         case WLAN_CIPHER_SUITE_TKIP:
358                 key->conf.iv_len = TKIP_IV_LEN;
359                 key->conf.icv_len = TKIP_ICV_LEN;
360                 if (seq) {
361                         for (i = 0; i < NUM_RX_DATA_QUEUES; i++) {
362                                 key->u.tkip.rx[i].iv32 =
363                                         get_unaligned_le32(&seq[2]);
364                                 key->u.tkip.rx[i].iv16 =
365                                         get_unaligned_le16(seq);
366                         }
367                 }
368                 spin_lock_init(&key->u.tkip.txlock);
369                 break;
370         case WLAN_CIPHER_SUITE_CCMP:
371                 key->conf.iv_len = CCMP_HDR_LEN;
372                 key->conf.icv_len = CCMP_MIC_LEN;
373                 if (seq) {
374                         for (i = 0; i < NUM_RX_DATA_QUEUES + 1; i++)
375                                 for (j = 0; j < CCMP_PN_LEN; j++)
376                                         key->u.ccmp.rx_pn[i][j] =
377                                                 seq[CCMP_PN_LEN - j - 1];
378                 }
379                 /*
380                  * Initialize AES key state here as an optimization so that
381                  * it does not need to be initialized for every packet.
382                  */
383                 key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(key_data);
384                 if (IS_ERR(key->u.ccmp.tfm)) {
385                         err = PTR_ERR(key->u.ccmp.tfm);
386                         kfree(key);
387                         return ERR_PTR(err);
388                 }
389                 break;
390         case WLAN_CIPHER_SUITE_AES_CMAC:
391                 key->conf.iv_len = 0;
392                 key->conf.icv_len = sizeof(struct ieee80211_mmie);
393                 if (seq)
394                         for (j = 0; j < 6; j++)
395                                 key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1];
396                 /*
397                  * Initialize AES key state here as an optimization so that
398                  * it does not need to be initialized for every packet.
399                  */
400                 key->u.aes_cmac.tfm =
401                         ieee80211_aes_cmac_key_setup(key_data);
402                 if (IS_ERR(key->u.aes_cmac.tfm)) {
403                         err = PTR_ERR(key->u.aes_cmac.tfm);
404                         kfree(key);
405                         return ERR_PTR(err);
406                 }
407                 break;
408         }
409         memcpy(key->conf.key, key_data, key_len);
410         INIT_LIST_HEAD(&key->list);
411
412         return key;
413 }
414
415 static void __ieee80211_key_destroy(struct ieee80211_key *key)
416 {
417         if (!key)
418                 return;
419
420         /*
421          * Synchronize so the TX path can no longer be using
422          * this key before we free/remove it.
423          */
424         synchronize_rcu();
425
426         if (key->local)
427                 ieee80211_key_disable_hw_accel(key);
428
429         if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP)
430                 ieee80211_aes_key_free(key->u.ccmp.tfm);
431         if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
432                 ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
433         if (key->local) {
434                 ieee80211_debugfs_key_remove(key);
435                 key->sdata->crypto_tx_tailroom_needed_cnt--;
436         }
437
438         kfree(key);
439 }
440
441 int ieee80211_key_link(struct ieee80211_key *key,
442                        struct ieee80211_sub_if_data *sdata,
443                        struct sta_info *sta)
444 {
445         struct ieee80211_key *old_key;
446         int idx, ret;
447         bool pairwise;
448
449         BUG_ON(!sdata);
450         BUG_ON(!key);
451
452         pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE;
453         idx = key->conf.keyidx;
454         key->local = sdata->local;
455         key->sdata = sdata;
456         key->sta = sta;
457
458         if (sta) {
459                 /*
460                  * some hardware cannot handle TKIP with QoS, so
461                  * we indicate whether QoS could be in use.
462                  */
463                 if (test_sta_flag(sta, WLAN_STA_WME))
464                         key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA;
465         } else {
466                 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
467                         struct sta_info *ap;
468
469                         /*
470                          * We're getting a sta pointer in, so must be under
471                          * appropriate locking for sta_info_get().
472                          */
473
474                         /* same here, the AP could be using QoS */
475                         ap = sta_info_get(key->sdata, key->sdata->u.mgd.bssid);
476                         if (ap) {
477                                 if (test_sta_flag(ap, WLAN_STA_WME))
478                                         key->conf.flags |=
479                                                 IEEE80211_KEY_FLAG_WMM_STA;
480                         }
481                 }
482         }
483
484         mutex_lock(&sdata->local->key_mtx);
485
486         if (sta && pairwise)
487                 old_key = key_mtx_dereference(sdata->local, sta->ptk);
488         else if (sta)
489                 old_key = key_mtx_dereference(sdata->local, sta->gtk[idx]);
490         else
491                 old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
492
493         increment_tailroom_need_count(sdata);
494
495         __ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
496         __ieee80211_key_destroy(old_key);
497
498         ieee80211_debugfs_key_add(key);
499
500         ret = ieee80211_key_enable_hw_accel(key);
501
502         mutex_unlock(&sdata->local->key_mtx);
503
504         return ret;
505 }
506
507 void __ieee80211_key_free(struct ieee80211_key *key)
508 {
509         if (!key)
510                 return;
511
512         /*
513          * Replace key with nothingness if it was ever used.
514          */
515         if (key->sdata)
516                 __ieee80211_key_replace(key->sdata, key->sta,
517                                 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
518                                 key, NULL);
519         __ieee80211_key_destroy(key);
520 }
521
522 void ieee80211_key_free(struct ieee80211_local *local,
523                         struct ieee80211_key *key)
524 {
525         mutex_lock(&local->key_mtx);
526         __ieee80211_key_free(key);
527         mutex_unlock(&local->key_mtx);
528 }
529
530 void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
531 {
532         struct ieee80211_key *key;
533
534         ASSERT_RTNL();
535
536         if (WARN_ON(!ieee80211_sdata_running(sdata)))
537                 return;
538
539         mutex_lock(&sdata->local->key_mtx);
540
541         sdata->crypto_tx_tailroom_needed_cnt = 0;
542
543         list_for_each_entry(key, &sdata->key_list, list) {
544                 increment_tailroom_need_count(sdata);
545                 ieee80211_key_enable_hw_accel(key);
546         }
547
548         mutex_unlock(&sdata->local->key_mtx);
549 }
550
551 void ieee80211_iter_keys(struct ieee80211_hw *hw,
552                          struct ieee80211_vif *vif,
553                          void (*iter)(struct ieee80211_hw *hw,
554                                       struct ieee80211_vif *vif,
555                                       struct ieee80211_sta *sta,
556                                       struct ieee80211_key_conf *key,
557                                       void *data),
558                          void *iter_data)
559 {
560         struct ieee80211_local *local = hw_to_local(hw);
561         struct ieee80211_key *key;
562         struct ieee80211_sub_if_data *sdata;
563
564         ASSERT_RTNL();
565
566         mutex_lock(&local->key_mtx);
567         if (vif) {
568                 sdata = vif_to_sdata(vif);
569                 list_for_each_entry(key, &sdata->key_list, list)
570                         iter(hw, &sdata->vif,
571                              key->sta ? &key->sta->sta : NULL,
572                              &key->conf, iter_data);
573         } else {
574                 list_for_each_entry(sdata, &local->interfaces, list)
575                         list_for_each_entry(key, &sdata->key_list, list)
576                                 iter(hw, &sdata->vif,
577                                      key->sta ? &key->sta->sta : NULL,
578                                      &key->conf, iter_data);
579         }
580         mutex_unlock(&local->key_mtx);
581 }
582 EXPORT_SYMBOL(ieee80211_iter_keys);
583
584 void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata)
585 {
586         struct ieee80211_key *key;
587
588         ASSERT_RTNL();
589
590         mutex_lock(&sdata->local->key_mtx);
591
592         list_for_each_entry(key, &sdata->key_list, list)
593                 ieee80211_key_disable_hw_accel(key);
594
595         mutex_unlock(&sdata->local->key_mtx);
596 }
597
598 void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
599 {
600         struct ieee80211_key *key, *tmp;
601
602         mutex_lock(&sdata->local->key_mtx);
603
604         ieee80211_debugfs_key_remove_mgmt_default(sdata);
605
606         list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
607                 __ieee80211_key_free(key);
608
609         ieee80211_debugfs_key_update_default(sdata);
610
611         mutex_unlock(&sdata->local->key_mtx);
612 }
613
614
615 void ieee80211_gtk_rekey_notify(struct ieee80211_vif *vif, const u8 *bssid,
616                                 const u8 *replay_ctr, gfp_t gfp)
617 {
618         struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
619
620         trace_api_gtk_rekey_notify(sdata, bssid, replay_ctr);
621
622         cfg80211_gtk_rekey_notify(sdata->dev, bssid, replay_ctr, gfp);
623 }
624 EXPORT_SYMBOL_GPL(ieee80211_gtk_rekey_notify);
625
626 void ieee80211_get_key_tx_seq(struct ieee80211_key_conf *keyconf,
627                               struct ieee80211_key_seq *seq)
628 {
629         struct ieee80211_key *key;
630         u64 pn64;
631
632         if (WARN_ON(!(keyconf->flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
633                 return;
634
635         key = container_of(keyconf, struct ieee80211_key, conf);
636
637         switch (key->conf.cipher) {
638         case WLAN_CIPHER_SUITE_TKIP:
639                 seq->tkip.iv32 = key->u.tkip.tx.iv32;
640                 seq->tkip.iv16 = key->u.tkip.tx.iv16;
641                 break;
642         case WLAN_CIPHER_SUITE_CCMP:
643                 pn64 = atomic64_read(&key->u.ccmp.tx_pn);
644                 seq->ccmp.pn[5] = pn64;
645                 seq->ccmp.pn[4] = pn64 >> 8;
646                 seq->ccmp.pn[3] = pn64 >> 16;
647                 seq->ccmp.pn[2] = pn64 >> 24;
648                 seq->ccmp.pn[1] = pn64 >> 32;
649                 seq->ccmp.pn[0] = pn64 >> 40;
650                 break;
651         case WLAN_CIPHER_SUITE_AES_CMAC:
652                 pn64 = atomic64_read(&key->u.aes_cmac.tx_pn);
653                 seq->ccmp.pn[5] = pn64;
654                 seq->ccmp.pn[4] = pn64 >> 8;
655                 seq->ccmp.pn[3] = pn64 >> 16;
656                 seq->ccmp.pn[2] = pn64 >> 24;
657                 seq->ccmp.pn[1] = pn64 >> 32;
658                 seq->ccmp.pn[0] = pn64 >> 40;
659                 break;
660         default:
661                 WARN_ON(1);
662         }
663 }
664 EXPORT_SYMBOL(ieee80211_get_key_tx_seq);
665
666 void ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf,
667                               int tid, struct ieee80211_key_seq *seq)
668 {
669         struct ieee80211_key *key;
670         const u8 *pn;
671
672         key = container_of(keyconf, struct ieee80211_key, conf);
673
674         switch (key->conf.cipher) {
675         case WLAN_CIPHER_SUITE_TKIP:
676                 if (WARN_ON(tid < 0 || tid >= NUM_RX_DATA_QUEUES))
677                         return;
678                 seq->tkip.iv32 = key->u.tkip.rx[tid].iv32;
679                 seq->tkip.iv16 = key->u.tkip.rx[tid].iv16;
680                 break;
681         case WLAN_CIPHER_SUITE_CCMP:
682                 if (WARN_ON(tid < -1 || tid >= NUM_RX_DATA_QUEUES))
683                         return;
684                 if (tid < 0)
685                         pn = key->u.ccmp.rx_pn[NUM_RX_DATA_QUEUES];
686                 else
687                         pn = key->u.ccmp.rx_pn[tid];
688                 memcpy(seq->ccmp.pn, pn, CCMP_PN_LEN);
689                 break;
690         case WLAN_CIPHER_SUITE_AES_CMAC:
691                 if (WARN_ON(tid != 0))
692                         return;
693                 pn = key->u.aes_cmac.rx_pn;
694                 memcpy(seq->aes_cmac.pn, pn, CMAC_PN_LEN);
695                 break;
696         }
697 }
698 EXPORT_SYMBOL(ieee80211_get_key_rx_seq);