cfg80211: implement wext key handling
[safe/jmp/linux-2.6] / net / mac80211 / wext.c
index 6b4eb8d..d845026 100644 (file)
 #include "aes_ccm.h"
 
 
-static int ieee80211_set_encryption(struct ieee80211_sub_if_data *sdata, u8 *sta_addr,
-                                   int idx, int alg, int remove,
-                                   int set_tx_key, const u8 *_key,
-                                   size_t key_len)
-{
-       struct ieee80211_local *local = sdata->local;
-       struct sta_info *sta;
-       struct ieee80211_key *key;
-       int err;
-
-       if (alg == ALG_AES_CMAC) {
-               if (idx < NUM_DEFAULT_KEYS ||
-                   idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) {
-                       printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d "
-                              "(BIP)\n", sdata->dev->name, idx);
-                       return -EINVAL;
-               }
-       } else if (idx < 0 || idx >= NUM_DEFAULT_KEYS) {
-               printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d\n",
-                      sdata->dev->name, idx);
-               return -EINVAL;
-       }
-
-       if (remove) {
-               rcu_read_lock();
-
-               err = 0;
-
-               if (is_broadcast_ether_addr(sta_addr)) {
-                       key = sdata->keys[idx];
-               } else {
-                       sta = sta_info_get(local, sta_addr);
-                       if (!sta) {
-                               err = -ENOENT;
-                               goto out_unlock;
-                       }
-                       key = sta->key;
-               }
-
-               ieee80211_key_free(key);
-       } else {
-               key = ieee80211_key_alloc(alg, idx, key_len, _key);
-               if (!key)
-                       return -ENOMEM;
-
-               sta = NULL;
-               err = 0;
-
-               rcu_read_lock();
-
-               if (!is_broadcast_ether_addr(sta_addr)) {
-                       set_tx_key = 0;
-                       /*
-                        * According to the standard, the key index of a
-                        * pairwise key must be zero. However, some AP are
-                        * broken when it comes to WEP key indices, so we
-                        * work around this.
-                        */
-                       if (idx != 0 && alg != ALG_WEP) {
-                               ieee80211_key_free(key);
-                               err = -EINVAL;
-                               goto out_unlock;
-                       }
-
-                       sta = sta_info_get(local, sta_addr);
-                       if (!sta) {
-                               ieee80211_key_free(key);
-                               err = -ENOENT;
-                               goto out_unlock;
-                       }
-               }
-
-               if (alg == ALG_WEP &&
-                       key_len != LEN_WEP40 && key_len != LEN_WEP104) {
-                       ieee80211_key_free(key);
-                       err = -EINVAL;
-                       goto out_unlock;
-               }
-
-               ieee80211_key_link(key, sdata, sta);
-
-               if (set_tx_key || (!sta && !sdata->default_key && key))
-                       ieee80211_set_default_key(sdata, idx);
-               if (alg == ALG_AES_CMAC &&
-                   (set_tx_key || (!sta && !sdata->default_mgmt_key && key)))
-                       ieee80211_set_default_mgmt_key(sdata, idx);
-       }
-
- out_unlock:
-       rcu_read_unlock();
-
-       return err;
-}
-
 static int ieee80211_ioctl_siwgenie(struct net_device *dev,
                                    struct iw_request_info *info,
                                    struct iw_point *data, char *extra)
@@ -472,109 +378,6 @@ static int ieee80211_ioctl_giwtxpower(struct net_device *dev,
        return 0;
 }
 
-static int ieee80211_ioctl_siwencode(struct net_device *dev,
-                                    struct iw_request_info *info,
-                                    struct iw_point *erq, char *keybuf)
-{
-       struct ieee80211_sub_if_data *sdata;
-       int idx, i, alg = ALG_WEP;
-       u8 bcaddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-       int remove = 0, ret;
-
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-       idx = erq->flags & IW_ENCODE_INDEX;
-       if (idx == 0) {
-               if (sdata->default_key)
-                       for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
-                               if (sdata->default_key == sdata->keys[i]) {
-                                       idx = i;
-                                       break;
-                               }
-                       }
-       } else if (idx < 1 || idx > 4)
-               return -EINVAL;
-       else
-               idx--;
-
-       if (erq->flags & IW_ENCODE_DISABLED)
-               remove = 1;
-       else if (erq->length == 0) {
-               /* No key data - just set the default TX key index */
-               ieee80211_set_default_key(sdata, idx);
-               return 0;
-       }
-
-       ret = ieee80211_set_encryption(
-               sdata, bcaddr,
-               idx, alg, remove,
-               !sdata->default_key,
-               keybuf, erq->length);
-
-       if (!ret && sdata->vif.type == NL80211_IFTYPE_STATION) {
-               if (remove)
-                       sdata->u.mgd.flags &= ~IEEE80211_STA_TKIP_WEP_USED;
-               else
-                       sdata->u.mgd.flags |= IEEE80211_STA_TKIP_WEP_USED;
-       }
-
-       return ret;
-}
-
-
-static int ieee80211_ioctl_giwencode(struct net_device *dev,
-                                    struct iw_request_info *info,
-                                    struct iw_point *erq, char *key)
-{
-       struct ieee80211_sub_if_data *sdata;
-       int idx, i;
-
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-       idx = erq->flags & IW_ENCODE_INDEX;
-       if (idx < 1 || idx > 4) {
-               idx = -1;
-               if (!sdata->default_key)
-                       idx = 0;
-               else for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
-                       if (sdata->default_key == sdata->keys[i]) {
-                               idx = i;
-                               break;
-                       }
-               }
-               if (idx < 0)
-                       return -EINVAL;
-       } else
-               idx--;
-
-       erq->flags = idx + 1;
-
-       if (!sdata->keys[idx]) {
-               erq->length = 0;
-               erq->flags |= IW_ENCODE_DISABLED;
-               return 0;
-       }
-
-       memcpy(key, sdata->keys[idx]->conf.key,
-              min_t(int, erq->length, sdata->keys[idx]->conf.keylen));
-       erq->length = sdata->keys[idx]->conf.keylen;
-       erq->flags |= IW_ENCODE_ENABLED;
-
-       if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-               switch (sdata->u.mgd.auth_alg) {
-               case WLAN_AUTH_OPEN:
-               case WLAN_AUTH_LEAP:
-                       erq->flags |= IW_ENCODE_OPEN;
-                       break;
-               case WLAN_AUTH_SHARED_KEY:
-                       erq->flags |= IW_ENCODE_RESTRICTED;
-                       break;
-               }
-       }
-
-       return 0;
-}
-
 static int ieee80211_ioctl_siwpower(struct net_device *dev,
                                    struct iw_request_info *info,
                                    struct iw_param *wrq,
@@ -809,82 +612,6 @@ static int ieee80211_ioctl_giwauth(struct net_device *dev,
 }
 
 
-static int ieee80211_ioctl_siwencodeext(struct net_device *dev,
-                                       struct iw_request_info *info,
-                                       struct iw_point *erq, char *extra)
-{
-       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
-       int uninitialized_var(alg), idx, i, remove = 0;
-
-       switch (ext->alg) {
-       case IW_ENCODE_ALG_NONE:
-               remove = 1;
-               break;
-       case IW_ENCODE_ALG_WEP:
-               alg = ALG_WEP;
-               break;
-       case IW_ENCODE_ALG_TKIP:
-               alg = ALG_TKIP;
-               break;
-       case IW_ENCODE_ALG_CCMP:
-               alg = ALG_CCMP;
-               break;
-       case IW_ENCODE_ALG_AES_CMAC:
-               alg = ALG_AES_CMAC;
-               break;
-       default:
-               return -EOPNOTSUPP;
-       }
-
-       if (erq->flags & IW_ENCODE_DISABLED)
-               remove = 1;
-
-       idx = erq->flags & IW_ENCODE_INDEX;
-       if (alg == ALG_AES_CMAC) {
-               if (idx < NUM_DEFAULT_KEYS + 1 ||
-                   idx > NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) {
-                       idx = -1;
-                       if (!sdata->default_mgmt_key)
-                               idx = 0;
-                       else for (i = NUM_DEFAULT_KEYS;
-                                 i < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS;
-                                 i++) {
-                               if (sdata->default_mgmt_key == sdata->keys[i])
-                               {
-                                       idx = i;
-                                       break;
-                               }
-                       }
-                       if (idx < 0)
-                               return -EINVAL;
-               } else
-                       idx--;
-       } else {
-               if (idx < 1 || idx > 4) {
-                       idx = -1;
-                       if (!sdata->default_key)
-                               idx = 0;
-                       else for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
-                               if (sdata->default_key == sdata->keys[i]) {
-                                       idx = i;
-                                       break;
-                               }
-                       }
-                       if (idx < 0)
-                               return -EINVAL;
-               } else
-                       idx--;
-       }
-
-       return ieee80211_set_encryption(sdata, ext->addr.sa_data, idx, alg,
-                                       remove,
-                                       ext->ext_flags &
-                                       IW_ENCODE_EXT_SET_TX_KEY,
-                                       ext->key, ext->key_len);
-}
-
-
 /* Structures to export the Wireless Handlers */
 
 static const iw_handler ieee80211_handler[] =
@@ -931,8 +658,8 @@ static const iw_handler ieee80211_handler[] =
        (iw_handler) ieee80211_ioctl_giwtxpower,        /* SIOCGIWTXPOW */
        (iw_handler) cfg80211_wext_siwretry,            /* SIOCSIWRETRY */
        (iw_handler) cfg80211_wext_giwretry,            /* SIOCGIWRETRY */
-       (iw_handler) ieee80211_ioctl_siwencode,         /* SIOCSIWENCODE */
-       (iw_handler) ieee80211_ioctl_giwencode,         /* SIOCGIWENCODE */
+       (iw_handler) cfg80211_wext_siwencode,           /* SIOCSIWENCODE */
+       (iw_handler) cfg80211_wext_giwencode,           /* SIOCGIWENCODE */
        (iw_handler) ieee80211_ioctl_siwpower,          /* SIOCSIWPOWER */
        (iw_handler) ieee80211_ioctl_giwpower,          /* SIOCGIWPOWER */
        (iw_handler) NULL,                              /* -- hole -- */
@@ -941,7 +668,7 @@ static const iw_handler ieee80211_handler[] =
        (iw_handler) NULL,                              /* SIOCGIWGENIE */
        (iw_handler) ieee80211_ioctl_siwauth,           /* SIOCSIWAUTH */
        (iw_handler) ieee80211_ioctl_giwauth,           /* SIOCGIWAUTH */
-       (iw_handler) ieee80211_ioctl_siwencodeext,      /* SIOCSIWENCODEEXT */
+       (iw_handler) cfg80211_wext_siwencodeext,        /* SIOCSIWENCODEEXT */
        (iw_handler) NULL,                              /* SIOCGIWENCODEEXT */
        (iw_handler) NULL,                              /* SIOCSIWPMKSA */
        (iw_handler) NULL,                              /* -- hole -- */