diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/wext.c | 279 |
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 | ||
30 | static 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 | |||
124 | static int ieee80211_ioctl_siwgenie(struct net_device *dev, | 30 | static 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 | ||
475 | static 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 | |||
525 | static 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 | |||
578 | static int ieee80211_ioctl_siwpower(struct net_device *dev, | 381 | static 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 | ||
812 | static 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 | ||
890 | static const iw_handler ieee80211_handler[] = | 617 | static 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 -- */ |