Example #1
0
int wpa_driver_awext_set_key(void *priv, wpa_alg alg,
			    const u8 *addr, int key_idx,
			    int set_tx, const u8 *seq, size_t seq_len,
			    const u8 *key, size_t key_len)
{
	struct wpa_driver_awext_data *drv = priv;
	return wpa_driver_wext_set_key(drv->wext, alg, addr, key_idx, set_tx, seq, seq_len, key, key_len);
}
Example #2
0
static int wpa_driver_tista_set_key(void *priv, wpa_alg alg,
                                    const u8 *addr, int key_idx,
                                    int set_tx, const u8 *seq, size_t seq_len,
                                    const u8 *key, size_t key_len)
{
    struct wpa_driver_ti_data *drv = priv;
    int ret;

    wpa_printf(MSG_DEBUG, "%s", __func__);
    TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
    ret = wpa_driver_wext_set_key(drv->wext, alg, addr, key_idx, set_tx,
                                  seq, seq_len, key, key_len);
    return ret;
}
static int wpa_ndiswrapper_set_key(void *priv, wpa_alg alg, const u8 *addr,
				   int key_idx, int set_tx,
				   const u8 *seq, size_t seq_len,
				   const u8 *key, size_t key_len)
{
	struct wpa_driver_ndiswrapper_data *drv = priv;
	struct wpa_key wpa_key;
	int ret = 0;
	struct iwreq priv_req;

	memset(&priv_req, 0, sizeof(priv_req));

	wpa_key.alg = alg;
	wpa_key.addr = addr;
	wpa_key.key_index = key_idx;
	wpa_key.set_tx = set_tx;
	wpa_key.seq = seq;
	wpa_key.seq_len = seq_len;
	wpa_key.key = key;
	wpa_key.key_len = key_len;

	priv_req.u.data.pointer = (void *)&wpa_key;
	priv_req.u.data.length = sizeof(wpa_key);

	if (iw_set_ext(drv, WPA_SET_KEY, &priv_req) < 0)
		ret = -1;

	if (alg == WPA_ALG_NONE) {
		/*
		 * ndiswrapper did not seem to be clearing keys properly in
		 * some cases with WPA_SET_KEY. For example, roaming from WPA
		 * enabled AP to plaintext one seemed to fail since the driver
		 * did not associate. Try to make sure the keys are cleared so
		 * that plaintext APs can be used in all cases.
		 */
		wpa_driver_wext_set_key(drv->wext, alg, addr, key_idx, set_tx,
					seq, seq_len, key, key_len);
	}

	return ret;
}
static int
wpa_driver_madwifi_set_key(void *priv, wpa_alg alg,
			   const u8 *addr, int key_idx, int set_tx,
			   const u8 *seq, size_t seq_len,
			   const u8 *key, size_t key_len)
{
	struct wpa_driver_madwifi_data *drv = priv;
	struct ieee80211req_key wk;
	char *alg_name;
	u_int8_t cipher;

	if (alg == WPA_ALG_NONE)
		return wpa_driver_madwifi_del_key(drv, key_idx, addr);

	switch (alg) {
	case WPA_ALG_WEP:
		if (addr == NULL || os_memcmp(addr, "\xff\xff\xff\xff\xff\xff",
					      ETH_ALEN) == 0) {
			/*
			 * madwifi did not seem to like static WEP key
			 * configuration with IEEE80211_IOCTL_SETKEY, so use
			 * Linux wireless extensions ioctl for this.
			 */
			return wpa_driver_wext_set_key(drv->wext, alg, addr,
						       key_idx, set_tx,
						       seq, seq_len,
						       key, key_len);
		}
		alg_name = "WEP";
		cipher = IEEE80211_CIPHER_WEP;
		break;
	case WPA_ALG_TKIP:
		alg_name = "TKIP";
		cipher = IEEE80211_CIPHER_TKIP;
		break;
	case WPA_ALG_CCMP:
		alg_name = "CCMP";
		cipher = IEEE80211_CIPHER_AES_CCM;
		break;
	default:
		wpa_printf(MSG_DEBUG, "%s: unknown/unsupported algorithm %d",
			__FUNCTION__, alg);
		return -1;
	}

	wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu "
		   "key_len=%lu", __FUNCTION__, alg_name, key_idx, set_tx,
		   (unsigned long) seq_len, (unsigned long) key_len);

	if (seq_len > sizeof(u_int64_t)) {
		wpa_printf(MSG_DEBUG, "%s: seq_len %lu too big",
			   __FUNCTION__, (unsigned long) seq_len);
		return -2;
	}
	if (key_len > sizeof(wk.ik_keydata)) {
		wpa_printf(MSG_DEBUG, "%s: key length %lu too big",
			   __FUNCTION__, (unsigned long) key_len);
		return -3;
	}

	os_memset(&wk, 0, sizeof(wk));
	wk.ik_type = cipher;
	wk.ik_flags = IEEE80211_KEY_RECV;
	if (addr == NULL ||
	    os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0)
		wk.ik_flags |= IEEE80211_KEY_GROUP;
	if (set_tx) {
		wk.ik_flags |= IEEE80211_KEY_XMIT | IEEE80211_KEY_DEFAULT;
		os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
	} else
		os_memset(wk.ik_macaddr, 0, IEEE80211_ADDR_LEN);
	wk.ik_keyix = key_idx;
	wk.ik_keylen = key_len;
#ifdef WORDS_BIGENDIAN
#define WPA_KEY_RSC_LEN 8
	{
		size_t i;
		u8 tmp[WPA_KEY_RSC_LEN];
		os_memset(tmp, 0, sizeof(tmp));
		for (i = 0; i < seq_len; i++)
			tmp[WPA_KEY_RSC_LEN - i - 1] = seq[i];
		os_memcpy(&wk.ik_keyrsc, tmp, WPA_KEY_RSC_LEN);
	}
#else /* WORDS_BIGENDIAN */
	os_memcpy(&wk.ik_keyrsc, seq, seq_len);
#endif /* WORDS_BIGENDIAN */
	os_memcpy(wk.ik_keydata, key, key_len);

	return set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk), 1);
}