Пример #1
0
static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
					  const struct wpa_eapol_key *key,
					  u16 ver)
{
	u16 key_info, keylen, len;
	const u8 *pos;
	struct wpa_eapol_ie_parse ie;

	wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
	wpa_printf(MSG_DEBUG, "WPA: RX message 3 of 4-Way Handshake from "
		   MACSTR " (ver=%d)", MAC2STR(sm->bssid), ver);

	key_info = WPA_GET_BE16(key->key_info);

	pos = (const u8 *) (key + 1);
	len = WPA_GET_BE16(key->key_data_length);
	wpa_hexdump(MSG_DEBUG, "WPA: IE KeyData", pos, len);
	wpa_supplicant_parse_ies(pos, len, &ie);
	if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
		wpa_printf(MSG_WARNING, "WPA: GTK IE in unencrypted key data");
		goto failed;
	}
#ifdef CONFIG_IEEE80211W
	if (ie.igtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
		wpa_printf(MSG_WARNING, "WPA: IGTK KDE in unencrypted key "
			   "data");
		goto failed;
	}

	if (ie.igtk && ie.igtk_len != sizeof(struct wpa_igtk_kde)) {
		wpa_printf(MSG_WARNING, "WPA: Invalid IGTK KDE length %lu",
			   (unsigned long) ie.igtk_len);
		goto failed;
	}
#endif /* CONFIG_IEEE80211W */

	if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0)
		goto failed;

	if (os_memcmp(sm->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
		wpa_printf(MSG_WARNING, "WPA: ANonce from message 1 of 4-Way "
			   "Handshake differs from 3 of 4-Way Handshake - drop"
			   " packet (src=" MACSTR ")", MAC2STR(sm->bssid));
		goto failed;
	}

	keylen = WPA_GET_BE16(key->key_length);
	switch (sm->pairwise_cipher) {
	case WPA_CIPHER_CCMP:
		if (keylen != 16) {
			wpa_printf(MSG_WARNING, "WPA: Invalid CCMP key length "
				   "%d (src=" MACSTR ")",
				   keylen, MAC2STR(sm->bssid));
			goto failed;
		}
		break;
	case WPA_CIPHER_TKIP:
		if (keylen != 32) {
			wpa_printf(MSG_WARNING, "WPA: Invalid TKIP key length "
				   "%d (src=" MACSTR ")",
				   keylen, MAC2STR(sm->bssid));
			goto failed;
		}
		break;
	}

	if (wpa_supplicant_send_4_of_4(sm, sm->bssid, key, ver, key_info,
				       NULL, 0, &sm->ptk)) {
		goto failed;
	}

	/* SNonce was successfully used in msg 3/4, so mark it to be renewed
	 * for the next 4-Way Handshake. If msg 3 is received again, the old
	 * SNonce will still be used to avoid changing PTK. */
	sm->renew_snonce = 1;

	if (key_info & WPA_KEY_INFO_INSTALL) {
		if (wpa_supplicant_install_ptk(sm, key))
			goto failed;
	}

	if (key_info & WPA_KEY_INFO_SECURE) {
		wpa_sm_mlme_setprotection(
			sm, sm->bssid, MLME_SETPROTECTION_PROTECT_TYPE_RX,
			MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
		eapol_sm_notify_portValid(sm->eapol, TRUE);
	}
	wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);

	if (ie.gtk &&
	    wpa_supplicant_pairwise_gtk(sm, key,
					ie.gtk, ie.gtk_len, key_info) < 0) {
		wpa_printf(MSG_INFO, "RSN: Failed to configure GTK");
		goto failed;
	}

	if (ieee80211w_set_keys(sm, &ie) < 0) {
		wpa_printf(MSG_INFO, "RSN: Failed to configure IGTK");
		goto failed;
	}

	return;

failed:
	wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
}
Пример #2
0
static void wpa_supplicant_process_stk_3_of_4(struct wpa_sm *sm,
					      struct wpa_peerkey *peerkey,
					      const struct wpa_eapol_key *key,
					      u16 ver)
{
	struct wpa_eapol_ie_parse kde;
	const u8 *keydata;
	size_t len, key_len;
	const u8 *_key;
	u8 key_buf[32], rsc[6];

	wpa_printf(MSG_DEBUG, "RSN: RX message 3 of STK 4-Way Handshake from "
		   MACSTR " (ver=%d)", MAC2STR(peerkey->addr), ver);

	os_memset(&kde, 0, sizeof(kde));

	/* RSN: msg 3/4 should contain Initiator RSN IE. It may also include
	 * Lifetime KDE. */
	keydata = (const u8 *) (key + 1);
	len = WPA_GET_BE16(key->key_data_length);
	wpa_hexdump(MSG_DEBUG, "RSN: msg 3/4 key data", keydata, len);
	if (wpa_supplicant_parse_ies(keydata, len, &kde) < 0) {
		wpa_printf(MSG_DEBUG, "RSN: Failed to parse key data in "
			   "STK 3/4");
		return;
	}

	if (kde.rsn_ie_len != peerkey->rsnie_i_len ||
	    os_memcmp(kde.rsn_ie, peerkey->rsnie_i, kde.rsn_ie_len) != 0) {
		wpa_printf(MSG_INFO, "RSN: Initiator RSN IE in SMK and STK "
			   "handshakes did not match");
		wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in SMK "
			    "handshake",
			    peerkey->rsnie_i, peerkey->rsnie_i_len);
		wpa_hexdump(MSG_DEBUG, "RSN: Initiator RSN IE in STK "
			    "handshake",
			    kde.rsn_ie, kde.rsn_ie_len);
		return;
	}

	if (os_memcmp(peerkey->inonce, key->key_nonce, WPA_NONCE_LEN) != 0) {
		wpa_printf(MSG_WARNING, "RSN: INonce from message 1 of STK "
			   "4-Way Handshake differs from 3 of STK 4-Way "
			   "Handshake - drop packet (src=" MACSTR ")",
			   MAC2STR(peerkey->addr));
		return;
	}

	wpa_supplicant_update_smk_lifetime(sm, peerkey, &kde);

	if (wpa_supplicant_send_4_of_4(sm, peerkey->addr, key, ver,
				       WPA_GET_BE16(key->key_info),
				       NULL, 0, &peerkey->stk))
		return;

	_key = (u8 *) peerkey->stk.tk1;
	if (peerkey->cipher == WPA_CIPHER_TKIP) {
		/* Swap Tx/Rx keys for Michael MIC */
		os_memcpy(key_buf, _key, 16);
		os_memcpy(key_buf + 16, peerkey->stk.u.auth.rx_mic_key, 8);
		os_memcpy(key_buf + 24, peerkey->stk.u.auth.tx_mic_key, 8);
		_key = key_buf;
		key_len = 32;
	} else
		key_len = 16;

	os_memset(rsc, 0, 6);
	if (wpa_sm_set_key(sm, peerkey->cipher, peerkey->addr, 0, 1,
			   rsc, sizeof(rsc), _key, key_len) < 0) {
		wpa_printf(MSG_WARNING, "RSN: Failed to set STK to the "
			   "driver.");
		return;
	}
}
Пример #3
0
static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
					  const struct wpa_eapol_key *key,  //size 95
					  u16 ver)
{
	u16 key_info, keylen, len;
	const u8 *pos;
	struct wpa_eapol_ie_parse ie;

	lwip_log("WPA: RX message 3 of 4-Way Handshake from "
		   MACSTR " (ver=%d)\n", MAC2STR(sm->bssid), ver);

	key_info = WPA_GET_BE16(key->key_info);

	pos = (const u8 *) (key + 1);
	len = WPA_GET_BE16(key->key_data_length);
	wpa_hexdump(MSG_DEBUG, "WPA: IE KeyData", pos, len);
	wpa_supplicant_parse_ies(pos, len, &ie);
	if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA))
    {
		lwip_log("WPA: GTK IE in unencrypted key data\n");        
		return;
	}

   	/*
    if (wpa_supplicant_validate_ie(sm, sm->bssid, &ie) < 0)
	{       
		return;
	}
    */	

	if (os_memcmp(sm->anonce, key->key_nonce, WPA_NONCE_LEN) != 0) 
    {
		lwip_log("WPA: ANonce from message 1 of 4-Way Handshake differs from 3 of 4-Way Handshake - drop"
			   " packet (src=" MACSTR ")\n", MAC2STR(sm->bssid));

       return;
	}

	keylen = WPA_GET_BE16(key->key_length);
	switch (sm->pairwise_cipher)
    {
    	case WPA_CIPHER_CCMP:
    		if (keylen != 16)
            {
    			lwip_log("WPA: Invalid CCMP key length %d (src=" MACSTR ")\n",
    				   keylen, MAC2STR(sm->bssid));
                return;
    		}
    		break;
			
    	case WPA_CIPHER_TKIP:
    		if (keylen != 32)
            {
    			lwip_log("WPA: Invalid TKIP key length %d (src=" MACSTR ")\n",
    				   keylen, MAC2STR(sm->bssid));
                return;
    		}
    		break;
	}

	if (wpa_supplicant_send_4_of_4(sm, sm->bssid, key, ver, key_info, NULL, 0, &sm->ptk))
	{
		return;
	}
	/* SNonce was successfully used in msg 3/4, so mark it to be renewed
	 * for the next 4-Way Handshake. If msg 3 is received again, the old
	 * SNonce will still be used to avoid changing PTK. */
	sm->renew_snonce = 1;

	if (key_info & WPA_KEY_INFO_INSTALL) 
	{
		wpa_supplicant_install_ptk(sm, key);
	}
	if (key_info & WPA_KEY_INFO_SECURE) 
	{
		//	wpa_sm_mlme_setprotection(
		//		sm, sm->bssid, MLME_SETPROTECTION_PROTECT_TYPE_RX,
		//		MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
		//	eapol_sm_notify_portValid(sm->eapol, TRUE);
	}
    
	//	wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
	if (ie.gtk && wpa_supplicant_pairwise_gtk(sm, key, ie.gtk, ie.gtk_len, key_info) < 0) 
	{
		lwip_log("RSN: Failed to configure GTK\n");
	}
	#if 1
	MSG_SET_WPA_SH();
	#else
	if (ieee80211w_set_keys(sm, &ie) < 0)
	{
		lwip_log("RSN: Failed to configure DHV/IGTK\n");
	}
    else
    {
       MSG_SET_WPA_SH();
    }
	#endif
}