Ejemplo n.º 1
0
/**
 * peerkey_verify_eapol_key_mic - Verify PeerKey MIC
 * @sm: Pointer to WPA state machine data from wpa_sm_init()
 * @peerkey: Pointer to the PeerKey data for the peer
 * @key: Pointer to the EAPOL-Key frame header
 * @ver: Version bits from EAPOL-Key Key Info
 * @buf: Pointer to the beginning of EAPOL-Key frame
 * @len: Length of the EAPOL-Key frame
 * Returns: 0 on success, -1 on failure
 */
int peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
				 struct wpa_peerkey *peerkey,
				 struct wpa_eapol_key *key, u16 ver,
				 const u8 *buf, size_t len)
{
	u8 mic[16];
	int ok = 0;

	if (peerkey->initiator && !peerkey->stk_set) {
		wpa_pmk_to_ptk(peerkey->smk, PMK_LEN, "Peer key expansion",
			       sm->own_addr, peerkey->addr,
			       peerkey->inonce, key->key_nonce,
			       (u8 *) &peerkey->stk, sizeof(peerkey->stk),
			       peerkey->use_sha256);
		peerkey->stk_set = 1;
	}

	os_memcpy(mic, key->key_mic, 16);
	if (peerkey->tstk_set) {
		os_memset(key->key_mic, 0, 16);
		wpa_eapol_key_mic(peerkey->tstk.kck, ver, buf, len,
				  key->key_mic);
		if (os_memcmp(mic, key->key_mic, 16) != 0) {
			wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
				   "when using TSTK - ignoring TSTK");
		} else {
			ok = 1;
			peerkey->tstk_set = 0;
			peerkey->stk_set = 1;
			os_memcpy(&peerkey->stk, &peerkey->tstk,
				  sizeof(peerkey->stk));
		}
	}

	if (!ok && peerkey->stk_set) {
		os_memset(key->key_mic, 0, 16);
		wpa_eapol_key_mic(peerkey->stk.kck, ver, buf, len,
				  key->key_mic);
		if (os_memcmp(mic, key->key_mic, 16) != 0) {
			wpa_printf(MSG_WARNING, "RSN: Invalid EAPOL-Key MIC "
				   "- dropping packet");
			return -1;
		}
		ok = 1;
	}

	if (!ok) {
		wpa_printf(MSG_WARNING, "RSN: Could not verify EAPOL-Key MIC "
			   "- dropping packet");
		return -1;
	}

	os_memcpy(peerkey->replay_counter, key->replay_counter,
		  WPA_REPLAY_COUNTER_LEN);
	peerkey->replay_counter_set = 1;
	return 0;
}
Ejemplo n.º 2
0
static int wpa_supplicant_verify_eapol_key_mic(struct wpa_sm *sm,
					       struct wpa_eapol_key *key,
					       u16 ver,
					       const u8 *buf, size_t len)
{
	u8 mic[16];
	int ok = 0;

	os_memcpy(mic, key->key_mic, 16);
	if (sm->tptk_set) 
	{
		os_memset(key->key_mic, 0, 16);
		wpa_eapol_key_mic(sm->tptk.kck, ver, buf, len, key->key_mic);
		if (os_memcmp(mic, key->key_mic, 16) != 0) 
		{
			lwip_log("WPA: Invalid EAPOL-Key MIC when using TPTK - ignoring TPTK\n");
		} 
		else 
		{
			ok = 1;
			sm->tptk_set = 0;
			sm->ptk_set = 1;
			os_memcpy(&sm->ptk, &sm->tptk, sizeof(sm->ptk));
		}
	}

	if (!ok && sm->ptk_set) 
	{
		os_memset(key->key_mic, 0, 16);
		wpa_eapol_key_mic(sm->ptk.kck, ver, buf, len, key->key_mic);
		if (os_memcmp(mic, key->key_mic, 16) != 0) 
		{
			lwip_log("WPA: Invalid EAPOL-Key MIC - dropping packet\n");
			return -1;
		}
		ok = 1;
	}

	if (!ok)
	{
		lwip_log("WPA: Could not verify EAPOL-Key MIC - dropping packet\n");
		return -1;
	}

	os_memcpy(sm->rx_replay_counter, key->replay_counter, WPA_REPLAY_COUNTER_LEN);
	sm->rx_replay_counter_set = 1;
	return 0;
}
Ejemplo n.º 3
0
static int check_mic(const u8 *kck, int ver, const u8 *data, size_t len)
{
	u8 *buf;
	int ret = -1;
	struct ieee802_1x_hdr *hdr;
	struct wpa_eapol_key *key;
	u8 rx_mic[16];

	buf = os_malloc(len);
	if (buf == NULL)
		return -1;
	os_memcpy(buf, data, len);
	hdr = (struct ieee802_1x_hdr *) buf;
	key = (struct wpa_eapol_key *) (hdr + 1);

	os_memcpy(rx_mic, key->key_mic, 16);
	os_memset(key->key_mic, 0, 16);

	if (wpa_eapol_key_mic(kck, ver, buf, len, key->key_mic) == 0 &&
	    os_memcmp(rx_mic, key->key_mic, 16) == 0)
		ret = 0;

	os_free(buf);

	return ret;
}
Ejemplo n.º 4
0
/**
 * wpa_eapol_key_send - Send WPA/RSN EAPOL-Key message
 * @sm: Pointer to WPA state machine data from wpa_sm_init()
 * @kck: Key Confirmation Key (KCK, part of PTK)
 * @ver: Version field from Key Info
 * @dest: Destination address for the frame
 * @proto: Ethertype (usually ETH_P_EAPOL)
 * @msg: EAPOL-Key message
 * @msg_len: Length of message
 * @key_mic: Pointer to the buffer to which the EAPOL-Key MIC is written
 */
void wpa_eapol_key_send(struct wpa_sm *sm, const u8 *kck,
			int ver, const u8 *dest, u16 proto,
			u8 *msg, size_t msg_len, u8 *key_mic)
{
	if (is_zero_ether_addr(dest) && is_zero_ether_addr(sm->bssid)) {
		/*
		 * Association event was not yet received; try to fetch
		 * BSSID from the driver.
		 */
		if (wpa_sm_get_bssid(sm, sm->bssid) < 0) {
			wpa_printf(MSG_DEBUG, "WPA: Failed to read BSSID for "
				   "EAPOL-Key destination address");
		} else {
			dest = sm->bssid;
			wpa_printf(MSG_DEBUG, "WPA: Use BSSID (" MACSTR
				   ") as the destination for EAPOL-Key",
				   MAC2STR(dest));
		}
	}
	if (key_mic &&
	    wpa_eapol_key_mic(kck, ver, msg, msg_len, key_mic)) {
		wpa_printf(MSG_ERROR, "WPA: Failed to generate EAPOL-Key "
			   "version %d MIC", ver);
		goto out;
	}
	wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key", msg, msg_len);
	wpa_sm_ether_send(sm, dest, proto, msg, msg_len);
	eapol_sm_notify_tx_eapol_key(sm->eapol);
out:
	os_free(msg);
}
Ejemplo n.º 5
0
static void wpa_eapol_key_send(struct wpa_sm *sm, const u8 *kck,
			       int ver, const u8 *dest, u16 proto,
			       u8 *msg, size_t msg_len, u8 *key_mic)
{
#if 0
	if (os_memcmp(dest, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0 &&
	    os_memcmp(sm->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0) {
		/*
		 * Association event was not yet received; try to fetch
		 * BSSID from the driver.
		 */
		if (wpa_sm_get_bssid(sm, sm->bssid) < 0) {
			lwip_log("WPA: Failed to read BSSID for EAPOL-Key destination address\n");
		} else {
			dest = sm->bssid;
			lwip_log("WPA: Use BSSID (" MACSTR ") as the destination for EAPOL-Key\n",
				   MAC2STR(dest));
		}
	}
#endif
	//generate MIC.
	if (key_mic) 
	{
		wpa_eapol_key_mic(kck, ver, msg, msg_len, key_mic);
	}
    
	wpa_ether_send(dest, proto, msg, msg_len);
	os_free(msg);
}