aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/wext.c279
1 files changed, 3 insertions, 276 deletions
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 6b4eb8d43a4e..d84502644686 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -27,100 +27,6 @@
27#include "aes_ccm.h" 27#include "aes_ccm.h"
28 28
29 29
30static int ieee80211_set_encryption(struct ieee80211_sub_if_data *sdata, u8 *sta_addr,
31 int idx, int alg, int remove,
32 int set_tx_key, const u8 *_key,
33 size_t key_len)
34{
35 struct ieee80211_local *local = sdata->local;
36 struct sta_info *sta;
37 struct ieee80211_key *key;
38 int err;
39
40 if (alg == ALG_AES_CMAC) {
41 if (idx < NUM_DEFAULT_KEYS ||
42 idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) {
43 printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d "
44 "(BIP)\n", sdata->dev->name, idx);
45 return -EINVAL;
46 }
47 } else if (idx < 0 || idx >= NUM_DEFAULT_KEYS) {
48 printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d\n",
49 sdata->dev->name, idx);
50 return -EINVAL;
51 }
52
53 if (remove) {
54 rcu_read_lock();
55
56 err = 0;
57
58 if (is_broadcast_ether_addr(sta_addr)) {
59 key = sdata->keys[idx];
60 } else {
61 sta = sta_info_get(local, sta_addr);
62 if (!sta) {
63 err = -ENOENT;
64 goto out_unlock;
65 }
66 key = sta->key;
67 }
68
69 ieee80211_key_free(key);
70 } else {
71 key = ieee80211_key_alloc(alg, idx, key_len, _key);
72 if (!key)
73 return -ENOMEM;
74
75 sta = NULL;
76 err = 0;
77
78 rcu_read_lock();
79
80 if (!is_broadcast_ether_addr(sta_addr)) {
81 set_tx_key = 0;
82 /*
83 * According to the standard, the key index of a
84 * pairwise key must be zero. However, some AP are
85 * broken when it comes to WEP key indices, so we
86 * work around this.
87 */
88 if (idx != 0 && alg != ALG_WEP) {
89 ieee80211_key_free(key);
90 err = -EINVAL;
91 goto out_unlock;
92 }
93
94 sta = sta_info_get(local, sta_addr);
95 if (!sta) {
96 ieee80211_key_free(key);
97 err = -ENOENT;
98 goto out_unlock;
99 }
100 }
101
102 if (alg == ALG_WEP &&
103 key_len != LEN_WEP40 && key_len != LEN_WEP104) {
104 ieee80211_key_free(key);
105 err = -EINVAL;
106 goto out_unlock;
107 }
108
109 ieee80211_key_link(key, sdata, sta);
110
111 if (set_tx_key || (!sta && !sdata->default_key && key))
112 ieee80211_set_default_key(sdata, idx);
113 if (alg == ALG_AES_CMAC &&
114 (set_tx_key || (!sta && !sdata->default_mgmt_key && key)))
115 ieee80211_set_default_mgmt_key(sdata, idx);
116 }
117
118 out_unlock:
119 rcu_read_unlock();
120
121 return err;
122}
123
124static int ieee80211_ioctl_siwgenie(struct net_device *dev, 30static int ieee80211_ioctl_siwgenie(struct net_device *dev,
125 struct iw_request_info *info, 31 struct iw_request_info *info,
126 struct iw_point *data, char *extra) 32 struct iw_point *data, char *extra)
@@ -472,109 +378,6 @@ static int ieee80211_ioctl_giwtxpower(struct net_device *dev,
472 return 0; 378 return 0;
473} 379}
474 380
475static int ieee80211_ioctl_siwencode(struct net_device *dev,
476 struct iw_request_info *info,
477 struct iw_point *erq, char *keybuf)
478{
479 struct ieee80211_sub_if_data *sdata;
480 int idx, i, alg = ALG_WEP;
481 u8 bcaddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
482 int remove = 0, ret;
483
484 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
485
486 idx = erq->flags & IW_ENCODE_INDEX;
487 if (idx == 0) {
488 if (sdata->default_key)
489 for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
490 if (sdata->default_key == sdata->keys[i]) {
491 idx = i;
492 break;
493 }
494 }
495 } else if (idx < 1 || idx > 4)
496 return -EINVAL;
497 else
498 idx--;
499
500 if (erq->flags & IW_ENCODE_DISABLED)
501 remove = 1;
502 else if (erq->length == 0) {
503 /* No key data - just set the default TX key index */
504 ieee80211_set_default_key(sdata, idx);
505 return 0;
506 }
507
508 ret = ieee80211_set_encryption(
509 sdata, bcaddr,
510 idx, alg, remove,
511 !sdata->default_key,
512 keybuf, erq->length);
513
514 if (!ret && sdata->vif.type == NL80211_IFTYPE_STATION) {
515 if (remove)
516 sdata->u.mgd.flags &= ~IEEE80211_STA_TKIP_WEP_USED;
517 else
518 sdata->u.mgd.flags |= IEEE80211_STA_TKIP_WEP_USED;
519 }
520
521 return ret;
522}
523
524
525static int ieee80211_ioctl_giwencode(struct net_device *dev,
526 struct iw_request_info *info,
527 struct iw_point *erq, char *key)
528{
529 struct ieee80211_sub_if_data *sdata;
530 int idx, i;
531
532 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
533
534 idx = erq->flags & IW_ENCODE_INDEX;
535 if (idx < 1 || idx > 4) {
536 idx = -1;
537 if (!sdata->default_key)
538 idx = 0;
539 else for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
540 if (sdata->default_key == sdata->keys[i]) {
541 idx = i;
542 break;
543 }
544 }
545 if (idx < 0)
546 return -EINVAL;
547 } else
548 idx--;
549
550 erq->flags = idx + 1;
551
552 if (!sdata->keys[idx]) {
553 erq->length = 0;
554 erq->flags |= IW_ENCODE_DISABLED;
555 return 0;
556 }
557
558 memcpy(key, sdata->keys[idx]->conf.key,
559 min_t(int, erq->length, sdata->keys[idx]->conf.keylen));
560 erq->length = sdata->keys[idx]->conf.keylen;
561 erq->flags |= IW_ENCODE_ENABLED;
562
563 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
564 switch (sdata->u.mgd.auth_alg) {
565 case WLAN_AUTH_OPEN:
566 case WLAN_AUTH_LEAP:
567 erq->flags |= IW_ENCODE_OPEN;
568 break;
569 case WLAN_AUTH_SHARED_KEY:
570 erq->flags |= IW_ENCODE_RESTRICTED;
571 break;
572 }
573 }
574
575 return 0;
576}
577
578static int ieee80211_ioctl_siwpower(struct net_device *dev, 381static int ieee80211_ioctl_siwpower(struct net_device *dev,
579 struct iw_request_info *info, 382 struct iw_request_info *info,
580 struct iw_param *wrq, 383 struct iw_param *wrq,
@@ -809,82 +612,6 @@ static int ieee80211_ioctl_giwauth(struct net_device *dev,
809} 612}
810 613
811 614
812static int ieee80211_ioctl_siwencodeext(struct net_device *dev,
813 struct iw_request_info *info,
814 struct iw_point *erq, char *extra)
815{
816 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
817 struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
818 int uninitialized_var(alg), idx, i, remove = 0;
819
820 switch (ext->alg) {
821 case IW_ENCODE_ALG_NONE:
822 remove = 1;
823 break;
824 case IW_ENCODE_ALG_WEP:
825 alg = ALG_WEP;
826 break;
827 case IW_ENCODE_ALG_TKIP:
828 alg = ALG_TKIP;
829 break;
830 case IW_ENCODE_ALG_CCMP:
831 alg = ALG_CCMP;
832 break;
833 case IW_ENCODE_ALG_AES_CMAC:
834 alg = ALG_AES_CMAC;
835 break;
836 default:
837 return -EOPNOTSUPP;
838 }
839
840 if (erq->flags & IW_ENCODE_DISABLED)
841 remove = 1;
842
843 idx = erq->flags & IW_ENCODE_INDEX;
844 if (alg == ALG_AES_CMAC) {
845 if (idx < NUM_DEFAULT_KEYS + 1 ||
846 idx > NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) {
847 idx = -1;
848 if (!sdata->default_mgmt_key)
849 idx = 0;
850 else for (i = NUM_DEFAULT_KEYS;
851 i < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS;
852 i++) {
853 if (sdata->default_mgmt_key == sdata->keys[i])
854 {
855 idx = i;
856 break;
857 }
858 }
859 if (idx < 0)
860 return -EINVAL;
861 } else
862 idx--;
863 } else {
864 if (idx < 1 || idx > 4) {
865 idx = -1;
866 if (!sdata->default_key)
867 idx = 0;
868 else for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
869 if (sdata->default_key == sdata->keys[i]) {
870 idx = i;
871 break;
872 }
873 }
874 if (idx < 0)
875 return -EINVAL;
876 } else
877 idx--;
878 }
879
880 return ieee80211_set_encryption(sdata, ext->addr.sa_data, idx, alg,
881 remove,
882 ext->ext_flags &
883 IW_ENCODE_EXT_SET_TX_KEY,
884 ext->key, ext->key_len);
885}
886
887
888/* Structures to export the Wireless Handlers */ 615/* Structures to export the Wireless Handlers */
889 616
890static const iw_handler ieee80211_handler[] = 617static const iw_handler ieee80211_handler[] =
@@ -931,8 +658,8 @@ static const iw_handler ieee80211_handler[] =
931 (iw_handler) ieee80211_ioctl_giwtxpower, /* SIOCGIWTXPOW */ 658 (iw_handler) ieee80211_ioctl_giwtxpower, /* SIOCGIWTXPOW */
932 (iw_handler) cfg80211_wext_siwretry, /* SIOCSIWRETRY */ 659 (iw_handler) cfg80211_wext_siwretry, /* SIOCSIWRETRY */
933 (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */ 660 (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */
934 (iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */ 661 (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */
935 (iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */ 662 (iw_handler) cfg80211_wext_giwencode, /* SIOCGIWENCODE */
936 (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */ 663 (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */
937 (iw_handler) ieee80211_ioctl_giwpower, /* SIOCGIWPOWER */ 664 (iw_handler) ieee80211_ioctl_giwpower, /* SIOCGIWPOWER */
938 (iw_handler) NULL, /* -- hole -- */ 665 (iw_handler) NULL, /* -- hole -- */
@@ -941,7 +668,7 @@ static const iw_handler ieee80211_handler[] =
941 (iw_handler) NULL, /* SIOCGIWGENIE */ 668 (iw_handler) NULL, /* SIOCGIWGENIE */
942 (iw_handler) ieee80211_ioctl_siwauth, /* SIOCSIWAUTH */ 669 (iw_handler) ieee80211_ioctl_siwauth, /* SIOCSIWAUTH */
943 (iw_handler) ieee80211_ioctl_giwauth, /* SIOCGIWAUTH */ 670 (iw_handler) ieee80211_ioctl_giwauth, /* SIOCGIWAUTH */
944 (iw_handler) ieee80211_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */ 671 (iw_handler) cfg80211_wext_siwencodeext, /* SIOCSIWENCODEEXT */
945 (iw_handler) NULL, /* SIOCGIWENCODEEXT */ 672 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
946 (iw_handler) NULL, /* SIOCSIWPMKSA */ 673 (iw_handler) NULL, /* SIOCSIWPMKSA */
947 (iw_handler) NULL, /* -- hole -- */ 674 (iw_handler) NULL, /* -- hole -- */