Example #1
0
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 (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);
	}

 out_unlock:
	rcu_read_unlock();

	return err;
}
Example #2
0
static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
                                    int idx, int alg, int remove,
                                    int set_tx_key, const u8 *_key,
                                    size_t key_len)
{
    struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
    struct sta_info *sta;
    struct ieee80211_key *key;
    struct ieee80211_sub_if_data *sdata;

    sdata = IEEE80211_DEV_TO_SUB_IF(dev);

    if (idx < 0 || idx >= NUM_DEFAULT_KEYS) {
        printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d\n",
               dev->name, idx);
        return -EINVAL;
    }

    if (remove) {
        if (is_broadcast_ether_addr(sta_addr)) {
            key = sdata->keys[idx];
        } else {
            sta = sta_info_get(local, sta_addr);
            if (!sta)
                return -ENOENT;
            key = sta->key;
        }

        if (!key)
            return -ENOENT;

        ieee80211_key_free(key);
        return 0;
    } else {
        key = ieee80211_key_alloc(alg, idx, key_len, _key);
        if (!key)
            return -ENOMEM;

        sta = NULL;

        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);
                return -EINVAL;
            }

            sta = sta_info_get(local, sta_addr);
            if (!sta) {
                ieee80211_key_free(key);
                return -ENOENT;
            }
        }

        ieee80211_key_link(key, sdata, sta);

        if (set_tx_key || (!sta && !sdata->default_key && key))
            ieee80211_set_default_key(sdata, idx);
    }

    return 0;
}