Beispiel #1
0
int
WIFI_group_key_set(const unsigned char* pKeyValue,
                   int keylength,
                   int key_idx,
                   const unsigned char* keyIV)
{
    struct wpa_supplicant *wpa_s = g_wpa_s;
    int alg;
    u8 msk_len;

    wpa_hexdump(MSG_DEBUG, "WIFI_group_key_set: KEYSC", keyIV, 16);
    wpa_printf(MSG_DEBUG, "[%s: %d] keylength = %d key_index = %d\n", __FUNCTION__, __LINE__, keylength, key_idx);
    alg = WPA_ALG_SMS4;
    msk_len = 32;

    if (wpa_drv_set_key(wpa_s,
                        alg,
                        (u8 *) "\xff\xff\xff\xff\xff\xff",
                        key_idx,
                        1,
                        keyIV,
                        16,
                        pKeyValue,
                        keylength) < 0)
    {
        wpa_printf(MSG_WARNING, "WPA: Failed to set MSK to "
                   "the driver.");
        return -1;
    }

    return 0;
}
Beispiel #2
0
static int supp_set_key(void *ctx, enum 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 ibss_rsn_peer *peer = ctx;

	wpa_printf(MSG_DEBUG, "SUPP: %s(alg=%d addr=" MACSTR " key_idx=%d "
		   "set_tx=%d)",
		   __func__, alg, MAC2STR(addr), key_idx, set_tx);
	wpa_hexdump(MSG_DEBUG, "SUPP: set_key - seq", seq, seq_len);
	wpa_hexdump_key(MSG_DEBUG, "SUPP: set_key - key", key, key_len);

	if (key_idx == 0) {
		/*
		 * In IBSS RSN, the pairwise key from the 4-way handshake
		 * initiated by the peer with highest MAC address is used.
		 */
		if (os_memcmp(peer->ibss_rsn->wpa_s->own_addr, peer->addr,
			      ETH_ALEN) > 0) {
			wpa_printf(MSG_DEBUG, "SUPP: Do not use this PTK");
			return 0;
		}
	}

	if (is_broadcast_ether_addr(addr))
		addr = peer->addr;
	return wpa_drv_set_key(peer->ibss_rsn->wpa_s, alg, addr, key_idx,
			       set_tx, seq, seq_len, key, key_len);
}
Beispiel #3
0
static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
			const u8 *addr, int idx, u8 *key, size_t key_len)
{
	struct ibss_rsn *ibss_rsn = ctx;
	u8 seq[6];

	os_memset(seq, 0, sizeof(seq));

	if (addr) {
		wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d addr=" MACSTR
			   " key_idx=%d)",
			   __func__, alg, MAC2STR(addr), idx);
	} else {
		wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d key_idx=%d)",
			   __func__, alg, idx);
	}
	wpa_hexdump_key(MSG_DEBUG, "AUTH: set_key - key", key, key_len);

	if (idx == 0) {
		/*
		 * In IBSS RSN, the pairwise key from the 4-way handshake
		 * initiated by the peer with highest MAC address is used.
		 */
		if (addr == NULL ||
		    os_memcmp(ibss_rsn->wpa_s->own_addr, addr, ETH_ALEN) < 0) {
			wpa_printf(MSG_DEBUG, "AUTH: Do not use this PTK");
			return 0;
		}
	}

	return wpa_drv_set_key(ibss_rsn->wpa_s, alg, addr, idx,
			       1, seq, 6, key, key_len);
}
Beispiel #4
0
static int wpa_supplicant_set_key(void *_wpa_s, enum 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_supplicant *wpa_s = _wpa_s;
	if (alg == WPA_ALG_TKIP && key_idx == 0 && key_len == 32) {
		/* Clear the MIC error counter when setting a new PTK. */
		wpa_s->mic_errors_seen = 0;
	}
#ifdef CONFIG_TESTING_GET_GTK
	if (key_idx > 0 && addr && is_broadcast_ether_addr(addr) &&
	    alg != WPA_ALG_NONE && key_len <= sizeof(wpa_s->last_gtk)) {
		os_memcpy(wpa_s->last_gtk, key, key_len);
		wpa_s->last_gtk_len = key_len;
	}
#endif /* CONFIG_TESTING_GET_GTK */
#ifdef CONFIG_TESTING_OPTIONS
	if (addr && !is_broadcast_ether_addr(addr)) {
		wpa_s->last_tk_alg = alg;
		os_memcpy(wpa_s->last_tk_addr, addr, ETH_ALEN);
		wpa_s->last_tk_key_idx = key_idx;
		if (key)
			os_memcpy(wpa_s->last_tk, key, key_len);
		wpa_s->last_tk_len = key_len;
	}
#endif /* CONFIG_TESTING_OPTIONS */
	return wpa_drv_set_key(wpa_s, alg, addr, key_idx, set_tx, seq, seq_len,
			       key, key_len);
}
static void ibss_rsn_handle_auth_1_of_2(struct ibss_rsn *ibss_rsn,
					struct ibss_rsn_peer *peer,
					const u8* addr)
{
	wpa_printf(MSG_DEBUG, "RSN: IBSS RX Auth frame (SEQ 1) from " MACSTR,
		   MAC2STR(addr));

	if (peer &&
	    peer->authentication_status & (IBSS_RSN_SET_PTK_SUPP |
					   IBSS_RSN_SET_PTK_AUTH)) {
		/* Clear the TK for this pair to allow recovery from the case
		 * where the peer STA has restarted and lost its key while we
		 * still have a pairwise key configured. */
		wpa_printf(MSG_DEBUG, "RSN: Clear pairwise key for peer "
			   MACSTR, MAC2STR(addr));
		wpa_drv_set_key(ibss_rsn->wpa_s, WPA_ALG_NONE, addr, 0, 0,
				NULL, 0, NULL, 0);
	}

	if (peer &&
	    peer->authentication_status & IBSS_RSN_AUTH_EAPOL_BY_PEER) {
		if (peer->own_auth_tx.sec) {
			struct os_reltime now, diff;
			os_get_reltime(&now);
			os_reltime_sub(&now, &peer->own_auth_tx, &diff);
			if (diff.sec == 0 && diff.usec < 500000) {
				wpa_printf(MSG_DEBUG, "RSN: Skip IBSS reinit since only %u usec from own Auth frame TX",
					   (int) diff.usec);
				goto skip_reinit;
			}
		}
		/*
		 * A peer sent us an Authentication frame even though it already
		 * started an EAPOL session. We should reinit state machines
		 * here, but it's much more complicated than just deleting and
		 * recreating the state machine
		 */
		wpa_printf(MSG_DEBUG, "RSN: IBSS Reinitializing station "
			   MACSTR, MAC2STR(addr));

		ibss_rsn_stop(ibss_rsn, addr);
		peer = NULL;
	}

	if (!peer) {
		peer = ibss_rsn_peer_init(ibss_rsn, addr);
		if (!peer)
			return;

		wpa_printf(MSG_DEBUG, "RSN: IBSS Auth started by peer " MACSTR,
			   MAC2STR(addr));
	}

skip_reinit:
	/* reply with an Authentication frame now, before sending an EAPOL */
	ibss_rsn_send_auth(ibss_rsn, addr, 2);
	/* no need to start another AUTH challenge in the other way.. */
	ibss_rsn_peer_authenticated(ibss_rsn, peer, IBSS_RSN_AUTH_EAPOL_BY_US);
}
Beispiel #6
0
static int __mesh_rsn_auth_init(struct mesh_rsn *rsn, const u8 *addr)
{
	struct wpa_auth_config conf;
	struct wpa_auth_callbacks cb;
	u8 seq[6] = {};

	wpa_printf(MSG_DEBUG, "AUTH: Initializing group state machine");

	os_memset(&conf, 0, sizeof(conf));
	conf.wpa = 2;
	conf.wpa_key_mgmt = WPA_KEY_MGMT_SAE;
	conf.wpa_pairwise = WPA_CIPHER_CCMP;
	conf.rsn_pairwise = WPA_CIPHER_CCMP;
	conf.wpa_group = WPA_CIPHER_CCMP;
	conf.eapol_version = 0;
	conf.wpa_group_rekey = -1;

	os_memset(&cb, 0, sizeof(cb));
	cb.ctx = rsn;
	cb.logger = auth_logger;
	cb.get_psk = auth_get_psk;
	cb.set_key = auth_set_key;
	cb.start_ampe = auth_start_ampe;

	rsn->auth = wpa_init(addr, &conf, &cb);
	if (rsn->auth == NULL) {
		wpa_printf(MSG_DEBUG, "AUTH: wpa_init() failed");
		return -1;
	}

	/* TODO: support rekeying */
	if (random_get_bytes(rsn->mgtk, 16) < 0) {
		wpa_deinit(rsn->auth);
		return -1;
	}

	/* group mgmt */
	wpa_drv_set_key(rsn->wpa_s, WPA_ALG_IGTK, NULL, 4, 1,
			seq, sizeof(seq), rsn->mgtk, sizeof(rsn->mgtk));

	/* group privacy / data frames */
	wpa_drv_set_key(rsn->wpa_s, WPA_ALG_CCMP, NULL, 1, 1,
			seq, sizeof(seq), rsn->mgtk, sizeof(rsn->mgtk));

	return 0;
}
Beispiel #7
0
static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol, int success,
				    void *ctx)
{
	struct wpa_supplicant *wpa_s = ctx;
	int res, pmk_len;
	u8 pmk[PMK_LEN];

	wpa_printf(MSG_DEBUG, "EAPOL authentication completed %ssuccessfully",
		   success ? "" : "un");

	if (wpas_wps_eapol_cb(wpa_s) > 0)
		return;

	if (!success) {
		/*
		 * Make sure we do not get stuck here waiting for long EAPOL
		 * timeout if the AP does not disconnect in case of
		 * authentication failure.
		 */
		wpa_supplicant_req_auth_timeout(wpa_s, 2, 0);
	}

	if (!success || !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
		return;

	if (!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt))
		return;

	wpa_printf(MSG_DEBUG, "Configure PMK for driver-based RSN 4-way "
		   "handshake");

	pmk_len = PMK_LEN;
	res = eapol_sm_get_key(eapol, pmk, PMK_LEN);
	if (res) {
		/*
		 * EAP-LEAP is an exception from other EAP methods: it
		 * uses only 16-byte PMK.
		 */
		res = eapol_sm_get_key(eapol, pmk, 16);
		pmk_len = 16;
	}

	if (res) {
		wpa_printf(MSG_DEBUG, "Failed to get PMK from EAPOL state "
			   "machines");
		return;
	}

	if (wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0, NULL, 0, pmk,
			    pmk_len)) {
		wpa_printf(MSG_DEBUG, "Failed to set PMK to the driver");
	}

	wpa_supplicant_cancel_scan(wpa_s);
	wpa_supplicant_cancel_auth_timeout(wpa_s);
	wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);

}
Beispiel #8
0
static int wpa_supplicant_key_mgmt_set_pmk(void *ctx, const u8 *pmk,
					   size_t pmk_len)
{
	struct wpa_supplicant *wpa_s = ctx;

	if (wpa_s->conf->key_mgmt_offload)
		return wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0,
				       NULL, 0, pmk, pmk_len);
	else
		return 0;
}
Beispiel #9
0
static int wpa_supplicant_key_mgmt_set_pmk(void *ctx, const u8 *pmk,
					   size_t pmk_len)
{
	struct wpa_supplicant *wpa_s = ctx;

	if (wpa_s->conf->key_mgmt_offload &&
	    (wpa_s->drv_flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD))
		return wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0,
				       NULL, 0, pmk, pmk_len);
	else
		return 0;
}
Beispiel #10
0
static int wpa_supplicant_set_key(void *_wpa_s, enum 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_supplicant *wpa_s = _wpa_s;
	if (alg == WPA_ALG_TKIP && key_idx == 0 && key_len == 32) {
		/* Clear the MIC error counter when setting a new PTK. */
		wpa_s->mic_errors_seen = 0;
	}
	return wpa_drv_set_key(wpa_s, alg, addr, key_idx, set_tx, seq, seq_len,
			       key, key_len);
}
Beispiel #11
0
/**
 * wpa_eapol_set_wep_key - set WEP key for the driver
 * @ctx: Pointer to wpa_supplicant data (wpa_s)
 * @unicast: 1 = individual unicast key, 0 = broadcast key
 * @keyidx: WEP key index (0..3)
 * @key: Pointer to key data
 * @keylen: Key length in bytes
 * Returns: 0 on success or < 0 on error.
 */
static int wpa_eapol_set_wep_key(void *ctx, int unicast, int keyidx,
				 const u8 *key, size_t keylen)
{
	struct wpa_supplicant *wpa_s = ctx;
	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
		int cipher = (keylen == 5) ? WPA_CIPHER_WEP40 :
			WPA_CIPHER_WEP104;
		if (unicast)
			wpa_s->pairwise_cipher = cipher;
		else
			wpa_s->group_cipher = cipher;
	}
	return wpa_drv_set_key(wpa_s, WPA_ALG_WEP,
			       unicast ? wpa_s->bssid : NULL,
			       keyidx, unicast, NULL, 0, key, keylen);
}
Beispiel #12
0
void ibss_rsn_connected(struct ibss_rsn *ibss_rsn)
{
	u8 seq[6];
	wpa_printf(MSG_DEBUG, "RSN: IBSS connected notification");
	if (ibss_rsn->init_gtk_idx) {
		wpa_printf(MSG_DEBUG, "RSN: Set initial IBSS TX GTK");
		os_memset(seq, 0, sizeof(seq));
		if (wpa_drv_set_key(ibss_rsn->wpa_s, WPA_ALG_CCMP,
				    broadcast_ether_addr,
				    ibss_rsn->init_gtk_idx,
				    1, seq, sizeof(seq), ibss_rsn->init_gtk,
				    16) < 0)
			wpa_printf(MSG_INFO, "RSN: Failed to set IBSS TX GTK");
		ibss_rsn->init_gtk_idx = 0;
		os_memset(ibss_rsn->init_gtk, 0, sizeof(ibss_rsn->init_gtk));
	}
}
Beispiel #13
0
static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
			const u8 *addr, int idx, u8 *key, size_t key_len)
{
	struct mesh_rsn *mesh_rsn = ctx;
	u8 seq[6];

	os_memset(seq, 0, sizeof(seq));

	if (addr) {
		wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d addr=" MACSTR
			   " key_idx=%d)",
			   __func__, alg, MAC2STR(addr), idx);
	} else {
		wpa_printf(MSG_DEBUG, "AUTH: %s(alg=%d key_idx=%d)",
			   __func__, alg, idx);
	}
	wpa_hexdump_key(MSG_DEBUG, "AUTH: set_key - key", key, key_len);

	return wpa_drv_set_key(mesh_rsn->wpa_s, alg, addr, idx,
			       1, seq, 6, key, key_len);
}
Beispiel #14
0
int
WIFI_unicast_key_set(const char* pKeyValue,
                     int keylength,
                     int key_idx)
{
    struct wpa_supplicant *wpa_s = g_wpa_s;

    int alg, keylen, rsclen;
    u8 *key_rsc;
    u8 null_rsc[16] = { 0, 0, 0, 0, 0, 0, 0, 0 };


    printf("[%s: %d] keylength = %d key_index = %d\n", __FUNCTION__, __LINE__, keylength, key_idx);

    alg = WPA_ALG_SMS4;
    keylen = 32;
    rsclen = 16;

    key_rsc = null_rsc;

    if (wpa_drv_set_key(wpa_s,
                        alg,
                        wpa_s->bssid,
                        key_idx,
                        1,
                        key_rsc,
                        rsclen,
                        (u8 *) pKeyValue,
                        keylen) < 0)
    {
        wpa_printf(MSG_WARNING, "WIFI_unicast_key_set: Failed to set PTK to the driver");
        return -1;
    }

    return 0;
}
Beispiel #15
0
static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol,
				    enum eapol_supp_result result,
				    void *ctx)
{
	struct wpa_supplicant *wpa_s = ctx;
	int res, pmk_len;
	u8 pmk[PMK_LEN];

	wpa_printf(MSG_DEBUG, "EAPOL authentication completed - result=%s",
		   result_str(result));

	if (wpas_wps_eapol_cb(wpa_s) > 0)
		return;

	wpa_s->eap_expected_failure = result ==
		EAPOL_SUPP_RESULT_EXPECTED_FAILURE;

	if (result != EAPOL_SUPP_RESULT_SUCCESS) {
		/*
		 * Make sure we do not get stuck here waiting for long EAPOL
		 * timeout if the AP does not disconnect in case of
		 * authentication failure.
		 */
		wpa_supplicant_req_auth_timeout(wpa_s, 2, 0);
	} else {
		ieee802_1x_notify_create_actor(wpa_s, wpa_s->last_eapol_src);
	}

	if (result != EAPOL_SUPP_RESULT_SUCCESS ||
	    !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
		return;

	if (!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt))
		return;

	wpa_printf(MSG_DEBUG, "Configure PMK for driver-based RSN 4-way "
		   "handshake");

	pmk_len = PMK_LEN;
	if (wpa_key_mgmt_ft(wpa_s->key_mgmt)) {
#ifdef CONFIG_IEEE80211R
		u8 buf[2 * PMK_LEN];
		wpa_printf(MSG_DEBUG, "RSN: Use FT XXKey as PMK for "
			   "driver-based 4-way hs and FT");
		res = eapol_sm_get_key(eapol, buf, 2 * PMK_LEN);
		if (res == 0) {
			os_memcpy(pmk, buf + PMK_LEN, PMK_LEN);
			os_memset(buf, 0, sizeof(buf));
		}
#else /* CONFIG_IEEE80211R */
		res = -1;
#endif /* CONFIG_IEEE80211R */
	} else {
		res = eapol_sm_get_key(eapol, pmk, PMK_LEN);
		if (res) {
			/*
			 * EAP-LEAP is an exception from other EAP methods: it
			 * uses only 16-byte PMK.
			 */
			res = eapol_sm_get_key(eapol, pmk, 16);
			pmk_len = 16;
		}
	}

	if (res) {
		wpa_printf(MSG_DEBUG, "Failed to get PMK from EAPOL state "
			   "machines");
		return;
	}

	wpa_hexdump_key(MSG_DEBUG, "RSN: Configure PMK for driver-based 4-way "
			"handshake", pmk, pmk_len);

	if (wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0, NULL, 0, pmk,
			    pmk_len)) {
		wpa_printf(MSG_DEBUG, "Failed to set PMK to the driver");
	}

	wpa_supplicant_cancel_scan(wpa_s);
	wpa_supplicant_cancel_auth_timeout(wpa_s);
	wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);

}