Example #1
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);
}
Example #2
0
static int wpa_supplicant_install_gtk(struct wpa_sm *sm, const struct wpa_gtk_data *gd, const u8 *key_rsc)
{
	const u8 *_gtk = gd->gtk;
	u8 gtk_buf[32];

	//printf("wpa_supplicant_install_gtk %d %d\n", sm->group_cipher, sm->pairwise_cipher);
	printf("igtk\n");
	if (sm->group_cipher == WPA_CIPHER_TKIP) 
	{
		/* Swap Tx/Rx keys for Michael MIC */
		os_memcpy(gtk_buf, gd->gtk, 16);
		os_memcpy(gtk_buf + 16, gd->gtk + 24, 8);
		os_memcpy(gtk_buf + 24, gd->gtk + 16, 8);
		_gtk = gtk_buf;
	}
	if (sm->pairwise_cipher == WPA_CIPHER_NONE) 
	{
		if (wpa_driver_wext_set_key_ext(sm, gd->alg,
				   (u8 *) "\xff\xff\xff\xff\xff\xff",
				   gd->keyidx, 1, key_rsc, gd->key_rsc_len,
				   _gtk, gd->gtk_len) < 0) 
		{
			lwip_log("WPA: Failed to set GTK to the driver (Group only).\n");
			return -1;
		}
	} 
	else if (wpa_driver_wext_set_key_ext(sm, gd->alg, (u8 *)"\xff\xff\xff\xff\xff\xff",
				  gd->keyidx, gd->tx, key_rsc, gd->key_rsc_len, _gtk, gd->gtk_len) < 0) 
	{
		lwip_log("WPA: Failed to set GTK to the driver.\n");
		return -1;
	}
	//printf("gtk end\n");
	return 0;
}
Example #3
0
static void wpa_report_ie_mismatch(struct wpa_sm *sm,
				   const char *reason, const u8 *src_addr,
				   const u8 *wpa_ie, size_t wpa_ie_len,
				   const u8 *rsn_ie, size_t rsn_ie_len)
{
	lwip_log("WPA: %s (src=" MACSTR ")\n",
		reason, MAC2STR(src_addr));

	if (sm->ap_wpa_ie) {
		wpa_hexdump(MSG_INFO, "WPA: WPA IE in Beacon/ProbeResp",
			    sm->ap_wpa_ie, sm->ap_wpa_ie_len);
	}
	if (wpa_ie) {
		if (!sm->ap_wpa_ie) {
			lwip_log("WPA: No WPA IE in Beacon/ProbeResp\n");
		}
		wpa_hexdump(MSG_INFO, "WPA: WPA IE in 3/4 msg",
			    wpa_ie, wpa_ie_len);
	}

	if (sm->ap_rsn_ie) {
		wpa_hexdump(MSG_INFO, "WPA: RSN IE in Beacon/ProbeResp",
			    sm->ap_rsn_ie, sm->ap_rsn_ie_len);
	}
	if (rsn_ie) {
		if (!sm->ap_rsn_ie) {
			lwip_log("WPA: No RSN IE in Beacon/ProbeResp\n");
		}
		wpa_hexdump(MSG_INFO, "WPA: RSN IE in 3/4 msg",
			    rsn_ie, rsn_ie_len);
	}
}
Example #4
0
static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
					  const unsigned char *src_addr,
					  const struct wpa_eapol_key *key,
					  u16 ver)
{
	int i;
	struct wpa_eapol_ie_parse ie;
	struct wpa_ptk *ptk;
	u8 buf[8];

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

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

	if (sm->proto == WPA_PROTO_RSN) 
	{
		/* RSN: msg 1/4 should contain PMKID for the selected PMK */
		const u8 *_buf = (const u8 *) (key + 1);
		size_t len = WPA_GET_BE16(key->key_data_length);
		wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", _buf, len);
		wpa_supplicant_parse_ies(_buf, len, &ie);
		if (ie.pmkid) 
		{
			wpa_hexdump(MSG_DEBUG, "RSN: PMKID from Authenticator", ie.pmkid, PMKID_LEN);
		}
	}

	if (sm->renew_snonce) 
    {
		if (hostapd_get_rand(sm->snonce, WPA_NONCE_LEN))
        {
			lwip_log("WPA: Failed to get random data for SNonce\n");
			return;
		}
		sm->renew_snonce = 0;
		wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce", sm->snonce, WPA_NONCE_LEN);
	}

	/* Calculate PTK which will be stored as a temporary PTK until it has
	 * been verified when processing message 3/4. */
	ptk = &sm->tptk;
	wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",
		       sm->own_addr, sm->bssid, sm->snonce, key->key_nonce,
		       (u8 *)ptk, sizeof(*ptk));

	/* Supplicant: swap tx/rx Mic keys */
	os_memcpy(buf, ptk->u.auth.tx_mic_key, 8);
	os_memcpy(ptk->u.auth.tx_mic_key, ptk->u.auth.rx_mic_key, 8);
	os_memcpy(ptk->u.auth.rx_mic_key, buf, 8);
	sm->tptk_set = 1;

    os_memcpy(sm->anonce, key->key_nonce, WPA_NONCE_LEN);
	if (wpa_supplicant_send_2_of_4(sm, sm->bssid, key, ver, sm->snonce,
				                   sm->assoc_wpa_ie, sm->assoc_wpa_ie_len, ptk))
	{
		return;
	}
}
Example #5
0
static int wpa_supplicant_check_group_cipher(int group_cipher,
					     int keylen, int maxkeylen,
					     int *key_rsc_len, wpa_alg *alg)
{
	int ret = 0;

	switch (group_cipher) {
	case WPA_CIPHER_CCMP:
		if (keylen != 16 || maxkeylen < 16) {
			ret = -1;
			break;
		}
		*key_rsc_len = 6;
		*alg = WPA_ALG_CCMP;
		break;
	case WPA_CIPHER_TKIP:
		if (keylen != 32 || maxkeylen < 32) {
			ret = -1;
			break;
		}
		*key_rsc_len = 6;
		*alg = WPA_ALG_TKIP;
		break;
	case WPA_CIPHER_WEP104:
		if (keylen != 13 || maxkeylen < 13) {
			ret = -1;
			break;
		}
		*key_rsc_len = 0;
		*alg = WPA_ALG_WEP;
		break;
	case WPA_CIPHER_WEP40:
		if (keylen != 5 || maxkeylen < 5) {
			ret = -1;
			break;
		}
		*key_rsc_len = 0;
		*alg = WPA_ALG_WEP;
		break;
	default:
		lwip_log("WPA: Unsupported Group Cipher %d\n",
			   group_cipher);
		return -1;
	}

	if (ret < 0 ) {
		lwip_log("WPA: Unsupported %s Group Cipher key length %d (%d).\n",
			   wpa_cipher_txt(group_cipher), keylen, maxkeylen);
	}

	return ret;
}
Example #6
0
static int ieee80211w_set_keys(struct wpa_sm *sm,
			       struct wpa_eapol_ie_parse *ie)
{
#ifdef CONFIG_IEEE80211W
	if (sm->mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC)
		return 0;

	if (ie->igtk) {
		const struct wpa_igtk_kde *igtk;
		u16 keyidx;
		if (ie->igtk_len != sizeof(*igtk))
			return -1;
		igtk = (const struct wpa_igtk_kde *) ie->igtk;
		keyidx = WPA_GET_LE16(igtk->keyid);
		lwip_log("WPA: IGTK keyid %d pn %02x%02x%02x%02x%02x%02x\n",
			   keyidx, MAC2STR(igtk->pn));
		wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK",
				igtk->igtk, WPA_IGTK_LEN);
		if (keyidx > 4095) {
			lwip_log("WPA: Invalid IGTK KeyID %d\n",
				   keyidx);
			return -1;
		}
		if (wpa_sm_set_key(sm, WPA_ALG_IGTK,
				   (u8 *) "\xff\xff\xff\xff\xff\xff",
				   keyidx, 0, igtk->pn, sizeof(igtk->pn),
				   igtk->igtk, WPA_IGTK_LEN) < 0) {
			lwip_log("WPA: Failed to configure IGTK to the driver\n");
			return -1;
		}
	}

	if (ie->dhv) {
		const struct wpa_dhv_kde *dhv;
		if (ie->dhv_len != sizeof(*dhv))
			return -1;
		dhv = (const struct wpa_dhv_kde *) ie->dhv;
		wpa_hexdump_key(MSG_DEBUG, "WPA: DHV", dhv->dhv, WPA_DHV_LEN);
		if (wpa_sm_set_key(sm, WPA_ALG_DHV,
				   (u8 *) "\xff\xff\xff\xff\xff\xff", 0, 0,
				   NULL, 0, dhv->dhv, WPA_DHV_LEN) < 0) {
			lwip_log("WPA: Failed to configure DHV to the driver\n");
			return -1;
		}
	}

	return 0;
#else /* CONFIG_IEEE80211W */
	return 0;
#endif /* CONFIG_IEEE80211W */
}
Example #7
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;
}
Example #8
0
static int wpa_supplicant_send_2_of_2(struct wpa_sm *sm,
				      const struct wpa_eapol_key *key,
				      int ver, u16 key_info)
{
	size_t rlen;
	struct wpa_eapol_key *reply;
	u8 *rbuf;
	
	printf("2/2\n");
	rbuf = wpa_alloc_eapol(IEEE802_1X_TYPE_EAPOL_KEY, NULL, sizeof(*reply), &rlen, (void *) &reply);
	if (rbuf == NULL)
		return -1;

	reply->type = sm->proto == WPA_PROTO_RSN ?
		EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
	key_info &= WPA_KEY_INFO_KEY_INDEX_MASK;
	key_info |= ver | WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE;
	WPA_PUT_BE16(reply->key_info, key_info);
	if (sm->proto == WPA_PROTO_RSN)
		WPA_PUT_BE16(reply->key_length, 0);
	else
		os_memcpy(reply->key_length, key->key_length, 2);
	os_memcpy(reply->replay_counter, key->replay_counter,
		  WPA_REPLAY_COUNTER_LEN);

	WPA_PUT_BE16(reply->key_data_length, 0);

	lwip_log("WPA: Sending EAPOL-Key 2/2\n");
	wpa_eapol_key_send(sm, sm->ptk.kck, ver, sm->bssid, ETH_P_EAPOL, rbuf, rlen, reply->key_mic);

	return 0;
}
Example #9
0
/* Decrypt RSN EAPOL-Key key data (RC4 or AES-WRAP) */
static int wpa_supplicant_decrypt_key_data(struct wpa_sm *sm,
					   struct wpa_eapol_key *key, u16 ver)
{
	u16 keydatalen = WPA_GET_BE16(key->key_data_length);

	wpa_hexdump(MSG_DEBUG, "RSN: encrypted key data",(u8 *) (key + 1), keydatalen);
	if (!sm->ptk_set) //wpa_supplicant_verify_eapol_key_mic ÖÐÉèÖÃ
    {
		lwip_log("WPA: PTK not available, cannot decrypt EAPOL-Key key data.\n");
		return -1;
	}

	/* Decrypt key data here so that this operation does not need
	 * to be implemented separately for each message type. */
	if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4)
    {
		u8 ek[32];
		os_memcpy(ek, key->key_iv, 16);
		os_memcpy(ek + 16, sm->ptk.kek, 16);
		rc4_skip(ek, 32, 256, (u8 *) (key + 1), keydatalen);
	} 
    else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES)
    {
		u8 buf[512];
		if (keydatalen % 8)
        {
			lwip_log("WPA: Unsupported AES-WRAP len %d\n", keydatalen);
			return -1;
		}
		keydatalen -= 8; /* AES-WRAP adds 8 bytes */
		if (buf == NULL)
        {
			lwip_log("WPA: No memory for AES-UNWRAP buffer\n");
			return -1;
		}
		if (aes_unwrap(sm->ptk.kek, keydatalen / 8, (u8 *)(key + 1), buf))
	    {
			lwip_log("WPA: AES unwrap failed - could not decrypt EAPOL-Key key data\n");
			return -1;
		}
		os_memcpy(key + 1, buf, keydatalen);
		WPA_PUT_BE16(key->key_data_length, keydatalen);
	}
	wpa_hexdump_key(MSG_DEBUG, "WPA: decrypted EAPOL-Key key data", (u8*)(key + 1), keydatalen);
	
	return 0;
}
Example #10
0
static int wpa_supplicant_install_ptk(struct wpa_sm *sm, const struct wpa_eapol_key *key)
{
	int keylen, rsclen, i;
	wpa_alg alg;
	const u8 *key_rsc;
	u8 null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };

	printf("iptk\n");
	switch (sm->pairwise_cipher) 
	{
	case WPA_CIPHER_CCMP:
		alg = WPA_ALG_CCMP;
		keylen = 16;
		rsclen = 6;
		break;
	case WPA_CIPHER_TKIP:
		alg = WPA_ALG_TKIP;
		keylen = 32;
		rsclen = 6;
		break;
	case WPA_CIPHER_NONE:
		lwip_log("WPA: Pairwise Cipher Suite: NONE - do not use pairwise keys\n");
		return 0;
	default:
		lwip_log("WPA: Unsupported pairwise cipher %d\n", sm->pairwise_cipher);
		return -1;
	}

	if (sm->proto == WPA_PROTO_RSN) 
	{
		key_rsc = null_rsc;
	} 
	else 
	{
		key_rsc = key->key_rsc;
	}

    if (wpa_driver_wext_set_key_ext(sm, alg, sm->bssid, 0, 1, key_rsc, rsclen, (u8*)sm->ptk.tk1, keylen) < 0)
    {
		lwip_log("WPA: Failed to set PTK to the driver.\n");
		return -1;       
    }
	return 0;
}
Example #11
0
static int wpa_supplicant_process_1_of_2_rsn(struct wpa_sm *sm, 
					     const u8 *keydata, size_t keydatalen, u16 key_info, struct wpa_gtk_data *gd)
{
	int maxkeylen;
	struct wpa_eapol_ie_parse ie;

	wpa_supplicant_parse_ies(keydata, keydatalen, &ie);
	if (ie.gtk && !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) 
	{
		lwip_log("WPA: GTK IE in unencrypted key data\n");
		return -1;
	}
	if (ie.gtk == NULL) 
	{
		lwip_log("WPA: No GTK IE in Group Key msg 1/2\n");
		return -1;
	}
	maxkeylen = gd->gtk_len = ie.gtk_len - 2;

	if (wpa_supplicant_check_group_cipher(sm->group_cipher,
					      gd->gtk_len, maxkeylen,
					      &gd->key_rsc_len, &gd->alg))
		return -1;

	wpa_hexdump(MSG_DEBUG, "RSN: received GTK in group key handshake",ie.gtk, ie.gtk_len);
	gd->keyidx = ie.gtk[0] & 0x3;
	gd->tx = wpa_supplicant_gtk_tx_bit_workaround(sm, !!(ie.gtk[0] & BIT(2)));
	if (ie.gtk_len - 2 > sizeof(gd->gtk))
	{
		lwip_log("RSN: Too long GTK in GTK IE (len=%lu)\n", (unsigned long) ie.gtk_len - 2);
		return -1;
	}
	os_memcpy(gd->gtk, ie.gtk + 2, ie.gtk_len - 2);

	#if 0
	if (ieee80211w_set_keys(sm, &ie) < 0)
		lwip_log("RSN: Failed to configure DHV/IGTK\n");
	#endif

	return 0;
}
Example #12
0
//发送数据
void udp_server_send_data(void){
	err_t err;
	if((lwip_flag&LWIP_SEND_DATA)==LWIP_SEND_DATA){
    ubuf = pbuf_alloc(PBUF_TRANSPORT, strlen((char *)lwip_demo_buf), PBUF_RAM); 
		ubuf->payload = lwip_demo_buf;
		err=udp_send(udp_server_pcb,ubuf);//发送数据
		if(err!=ERR_OK){
			lwip_log("UDP SERVER发送数据失败!");
		}
	  lwip_flag &=~LWIP_SEND_DATA;		//清除发送数据的标志
		pbuf_free(ubuf);
	}
}
Example #13
0
static int wpa_supplicant_gtk_tx_bit_workaround(const struct wpa_sm *sm,
						int tx)
{
	if (tx && sm->pairwise_cipher != WPA_CIPHER_NONE) {
		/* Ignore Tx bit for GTK if a pairwise key is used. One AP
		 * seemed to set this bit (incorrectly, since Tx is only when
		 * doing Group Key only APs) and without this workaround, the
		 * data connection does not work because wpa_supplicant
		 * configured non-zero keyidx to be used for unicast. */
		lwip_log("WPA: Tx bit set for GTK, but pairwise keys are used - ignore Tx bit\n");
		return 0;
	}
	return tx;
}
Example #14
0
static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
				      const unsigned char *src_addr,
				      struct wpa_eapol_ie_parse *ie)
{
	struct wpa_ssid *ssid = sm->cur_ssid; //wp

	if (sm->ap_wpa_ie == NULL && sm->ap_rsn_ie == NULL) 
	{
		lwip_log("WPA: No WPA/RSN IE for this AP known. Trying to get from scan results\n");
	}

	if (ie->wpa_ie == NULL && ie->rsn_ie == NULL && (sm->ap_wpa_ie || sm->ap_rsn_ie)) 
	{
		wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match "
				       "with IE in Beacon/ProbeResp (no IE?)",
				       src_addr, ie->wpa_ie, ie->wpa_ie_len,
				       ie->rsn_ie, ie->rsn_ie_len);        
        return -1;
	}

	if ((ie->wpa_ie && sm->ap_wpa_ie &&
	     (ie->wpa_ie_len != sm->ap_wpa_ie_len ||
	      os_memcmp(ie->wpa_ie, sm->ap_wpa_ie, ie->wpa_ie_len) != 0)) ||
	    (ie->rsn_ie && sm->ap_rsn_ie &&
	     (ie->rsn_ie_len != sm->ap_rsn_ie_len ||
	      os_memcmp(ie->rsn_ie, sm->ap_rsn_ie, ie->rsn_ie_len) != 0))) 
	{
		wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match with IE in Beacon/ProbeResp",
				       src_addr, ie->wpa_ie, ie->wpa_ie_len,
				       ie->rsn_ie, ie->rsn_ie_len);
        
        return -1;
	}

	if (sm->proto == WPA_PROTO_WPA &&
	    ie->rsn_ie && sm->ap_rsn_ie == NULL &&
	    ssid && (ssid->proto & WPA_PROTO_RSN)) {
		wpa_report_ie_mismatch(sm, "Possible downgrade attack "
				       "detected - RSN was enabled and RSN IE "
				       "was in msg 3/4, but not in "
				       "Beacon/ProbeResp",
				       src_addr, ie->wpa_ie, ie->wpa_ie_len,
				       ie->rsn_ie, ie->rsn_ie_len);        
        return -1;
	}

	return 0;
}
Example #15
0
//连接轮询时将要调用的函数
err_t tcp_server_poll(void *arg, struct tcp_pcb *tpcb){
		err_t ret_err;
		struct tcp_server_state* ts;
	  ts = arg;
		lwip_log("tcp_server_polling!\r\n");
		if(ts!=NULL){		//连接处于空闲可以发送数据
				if((lwip_flag&LWIP_SEND_DATA)==LWIP_SEND_DATA){
						tcp_write(tpcb,lwip_demo_buf,strlen((char *)lwip_demo_buf),1);//发送数据
					  lwip_flag &=~LWIP_SEND_DATA;		//清除发送数据的标志
				}
		}else{
			tcp_abort(tpcb);
			ret_err = ERR_ABRT;
		}
		return ret_err;
}
Example #16
0
static int wpa_supplicant_send_2_of_4(struct wpa_sm *sm,
				      const unsigned char *dst,
				      const struct wpa_eapol_key *key,
				      int ver, const u8 *nonce,
				      const u8 *wpa_ie, size_t wpa_ie_len,
				      struct wpa_ptk *ptk)
{
	size_t rlen;
	struct wpa_eapol_key *reply;
	u8 *rbuf;

	if (wpa_ie == NULL) 
	{
		lwip_log("WPA: No wpa_ie set - cannot generate msg 2/4\n");
		return -1;
	}

	wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);

	rbuf = wpa_alloc_eapol(IEEE802_1X_TYPE_EAPOL_KEY,
                           NULL, sizeof(*reply) + wpa_ie_len,
                           &rlen, (void *) &reply);
	if (rbuf == NULL)
		return -1;

	reply->type = sm->proto == WPA_PROTO_RSN ? EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
	WPA_PUT_BE16(reply->key_info, ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC);
	if (sm->proto == WPA_PROTO_RSN)
		WPA_PUT_BE16(reply->key_length, 0);
	else
		os_memcpy(reply->key_length, key->key_length, 2);
	os_memcpy(reply->replay_counter, key->replay_counter, WPA_REPLAY_COUNTER_LEN);

	WPA_PUT_BE16(reply->key_data_length, wpa_ie_len);
	os_memcpy(reply + 1, wpa_ie, wpa_ie_len);

	os_memcpy(reply->key_nonce, nonce, WPA_NONCE_LEN);
    
	wpa_eapol_key_send(sm, ptk->kck, ver, dst, ETH_P_EAPOL, rbuf, rlen, reply->key_mic);
	//printf("wpa_supplicant_process_2_of_4 exit\n");
	printf("2/4x\n");
	return 0;
}
Example #17
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
}
Example #18
0
static int wpa_supplicant_process_1_of_2_wpa(struct wpa_sm *sm,
					     const struct wpa_eapol_key *key,
					     size_t keydatalen, int key_info,
					     size_t extra_len, u16 ver,
					     struct wpa_gtk_data *gd)
{
	size_t maxkeylen;
	u8 ek[32];

	gd->gtk_len = WPA_GET_BE16(key->key_length);
	maxkeylen = keydatalen;
	if (keydatalen > extra_len) 
	{
		lwip_log("WPA: Truncated EAPOL-Key packet: key_data_length=%lu > extra_len=%lu\n",
			   (unsigned long) keydatalen,
			   (unsigned long) extra_len);
		return -1;
	}
	if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) 
	{
		if (maxkeylen < 8) 
		{
			lwip_log("WPA: Too short maxkeylen (%lu)\n",
				   (unsigned long) maxkeylen);
			return -1;
		}
		maxkeylen -= 8;
	}

	if (wpa_supplicant_check_group_cipher(sm->group_cipher,
					      gd->gtk_len, maxkeylen,
					      &gd->key_rsc_len, &gd->alg))
		return -1;

	gd->keyidx = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >> WPA_KEY_INFO_KEY_INDEX_SHIFT;
	
	if (ver == WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) 
	{
		os_memcpy(ek, key->key_iv, 16);
		os_memcpy(ek + 16, sm->ptk.kek, 16);
		if (keydatalen > sizeof(gd->gtk)) 
		{
			lwip_log("WPA: RC4 key data too long (%lu)\n",
				   (unsigned long) keydatalen);
			return -1;
		}
		os_memcpy(gd->gtk, key + 1, keydatalen);
		rc4_skip(ek, 32, 256, gd->gtk, keydatalen);
	} 
	else if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) 
	{
		if (keydatalen % 8) 
		{
			lwip_log("WPA: Unsupported AES-WRAP len %lu\n", (unsigned long) keydatalen);
			return -1;
		}
		if (maxkeylen > sizeof(gd->gtk)) 
		{
			lwip_log("WPA: AES-WRAP key data too long (keydatalen=%lu maxkeylen=%lu)\n",
				   (unsigned long) keydatalen,
				   (unsigned long) maxkeylen);
			return -1;
		}
		if (aes_unwrap(sm->ptk.kek, maxkeylen/8, (const u8 *)(key + 1), gd->gtk)) 
		{
			lwip_log("WPA: AES unwrap failed - could not decrypt GTK\n");
			return -1;
		}
	}
	gd->tx = wpa_supplicant_gtk_tx_bit_workaround(sm, !!(key_info & WPA_KEY_INFO_TXRX));
	
	return 0;
}
Example #19
0
/**
 * wpa_sm_rx_eapol - Process received WPA EAPOL frames
 * @sm: Pointer to WPA state machine data from wpa_sm_init()
 * @src_addr: Source MAC address of the EAPOL packet
 * @buf: Pointer to the beginning of the EAPOL data (EAPOL header)
 * @len: Length of the EAPOL frame
 * Returns: 1 = WPA EAPOL-Key processed, 0 = not a WPA EAPOL-Key, -1 failure
 *
 * This function is called for each received EAPOL frame. Other than EAPOL-Key
 * frames can be skipped if filtering is done elsewhere. wpa_sm_rx_eapol() is
 * only processing WPA and WPA2 EAPOL-Key frames.
 *
 * The received EAPOL-Key packets are validated and valid packets are replied
 * to. In addition, key material (PTK, GTK) is configured at the end of a
 * successful key handshake.
 */
int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr, u8 *buf, size_t len)
{
	size_t plen, data_len, extra_len;
	struct ieee802_1x_hdr *hdr;
	struct wpa_eapol_key *key;
	u16 key_info, ver;
	int ret = -1;
	
	if (len < (sizeof(*hdr) + sizeof(*key))) 
	{
		lwip_log("WPA: EAPOL frame too short to be a WPA EAPOL-Key (len %lu, expecting at least %lu)\n",
			      (unsigned long) len, (unsigned long) sizeof(*hdr) + sizeof(*key));
		return 0;
	}

	hdr = (struct ieee802_1x_hdr *)buf;
	key = (struct wpa_eapol_key *)(hdr + 1);
	plen = be_to_host16(hdr->length);
	data_len = plen + sizeof(*hdr);
	
	lwip_log("IEEE 802.1X RX: version=%d type=%d length=%lu\n", hdr->version, hdr->type, plen);
	if (hdr->version < EAPOL_VERSION) 
	{
		/* TODO: backwards compatibility */
	}
	if (hdr->type != IEEE802_1X_TYPE_EAPOL_KEY) 
	{
		lwip_log("WPA: EAPOL frame (type %u) discarded, not a Key frame\n", hdr->type);
		ret = 0;
		goto out;
	}
	
	if (data_len < len) 
	{
		lwip_log("WPA: ignoring %lu bytes after the IEEE 802.1X data\n", (unsigned long) len - data_len);
	}

	/* dgl: len = struct ieee802_1x_hdr + struct wpa_eapol_key + key.data + null.data */
	if ((plen > len - sizeof(*hdr)) || (plen < sizeof(*key))) 
	{
		lwip_log("WPA: EAPOL frame payload size %lu invalid (frame size %lu)\n", plen, len);
		ret = 0;
		goto out;
	}

	if ((key->type != EAPOL_KEY_TYPE_WPA) && (key->type != EAPOL_KEY_TYPE_RSN))
	{
		lwip_log("WPA: EAPOL-Key type (%d) unknown, discarded\n", key->type);
		ret = 0;
		goto out;
	}

	key_info = WPA_GET_BE16(key->key_info);
	ver = key_info & WPA_KEY_INFO_TYPE_MASK;
	if ((ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4) && (ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES))
	{
		lwip_log("WPA: Unsupported EAPOL-Key descriptor version %d.\n", ver);
		goto out;
	}

	if (sm->pairwise_cipher == WPA_CIPHER_CCMP && ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) 
	{
		lwip_log("WPA: CCMP is used, but EAPOL-Key descriptor version (%d) is not 2.\n", ver);
		if (sm->group_cipher != WPA_CIPHER_CCMP && !(key_info & WPA_KEY_INFO_KEY_TYPE)) 
		{
			/* Earlier versions of IEEE 802.11i did not explicitly
			 * require version 2 descriptor for all EAPOL-Key
			 * packets, so allow group keys to use version 1 if
			 * CCMP is not used for them. */
			lwip_log("WPA: Backwards compatibility: allow invalid version for non-CCMP group keys\n");
		} 
		else
		{
			goto out;
		}
	}
	
    /*
    if (!peerkey && sm->rx_replay_counter_set &&
	    os_memcmp(key->replay_counter, sm->rx_replay_counter, WPA_REPLAY_COUNTER_LEN) <= 0)
    {
		printf("WPA: EAPOL-Key Replay Counter did not increase - dropping packet\n");
		goto out;
	}
	*/
	//printf("wpa now:%d old:%d\n", key->replay_counter, sm->rx_replay_counter);

	if (!(key_info & (WPA_KEY_INFO_ACK | WPA_KEY_INFO_SMK_MESSAGE)))
    {
		lwip_log("WPA: No Ack bit in key_info\n");
		goto out;
	}

	if (key_info & WPA_KEY_INFO_REQUEST)
    {
		lwip_log("WPA: EAPOL-Key with Request bit - dropped\n");
		goto out;
	}
   
	if ((key_info & WPA_KEY_INFO_MIC) && wpa_supplicant_verify_eapol_key_mic(sm, key, ver, buf, data_len))
	{
		goto out;
	}

	extra_len = data_len - sizeof(*hdr) - sizeof(*key);
	if (WPA_GET_BE16(key->key_data_length) > extra_len) 
    {
		lwip_log("WPA: Invalid EAPOL-Key frame - key_data overflow (%d > %lu)\n",
			      WPA_GET_BE16(key->key_data_length), (unsigned long)extra_len);
		goto out;
	}
	extra_len = WPA_GET_BE16(key->key_data_length);

	if (sm->proto == WPA_PROTO_RSN && (key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) 
    {
		if (wpa_supplicant_decrypt_key_data(sm, key, ver))
			goto out;
		extra_len = WPA_GET_BE16(key->key_data_length);
	}    
    
    if (key_info & WPA_KEY_INFO_KEY_TYPE)
    {
		if (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) 
		{
			lwip_log("WPA: Ignored EAPOL-Key (Pairwise) with non-zero key index\n");
			goto out;
		}

		if (key_info & WPA_KEY_INFO_MIC) 
		{
			/* 3/4 4-Way Handshake */
    		//printf("wpa_supplicant_process_3_of_4 exit\n");
    		printf("3/4x\n");
			wpa_supplicant_process_3_of_4(sm, key, ver);
		} 
		else 
		{
			/* 1/4 4-Way Handshake */
			//printf("wpa_supplicant_process_1_of_4 exit\n");
			printf("1/4x\n");
			MSG_CLR_WPA_SH();
			wpa_supplicant_process_1_of_4(sm, src_addr, key, ver);
		}
	} 
    else if (key_info & WPA_KEY_INFO_SMK_MESSAGE)
    {
	} 
    else
    {
		if (key_info & WPA_KEY_INFO_MIC)
        {
			/* 1/2 Group Key Handshake */
			//printf("wpa_supplicant_process_1_of_2\n");
			printf("1/2\n");
			wpa_supplicant_process_1_of_2(sm, src_addr, key, extra_len, ver);
		} 
        else
        {
			lwip_log("WPA: EAPOL-Key (Group) without Mic bit - dropped\n");
		}
	}
	ret = 1;
out:
    //printf("wpa_sm_rx_eapol exit\n");
	return ret;
}
Example #20
0
/**
 * wpa_supplicant_parse_ies - Parse EAPOL-Key Key Data IEs
 * @buf: Pointer to the Key Data buffer
 * @len: Key Data Length
 * @ie: Pointer to parsed IE data
 * Returns: 0 on success, -1 on failure
 */
static int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
				    struct wpa_eapol_ie_parse *ie)
{
	const u8 *pos, *end;
	int ret = 0;

	os_memset(ie, 0, sizeof(*ie));


     //check ccmp
     #if 0
     {
        unsigned short i, CipherCnt;

        if(((unsigned char *)buf)[0] == 0x30)
        {
            CipherCnt = ((unsigned short *)buf)[4];

            if(CipherCnt > 1)
            {

                for(i = 0; i < CipherCnt; i++)
                {                    
                    if(((unsigned char *)buf)[13 + i * 4] == 4)
                    {
                        //exist ccmp
                        break;
                    }                   
                }

                if(i >= CipherCnt)
                {
                    // not exist ccmp, select default
                    //memcpy((void*)bssp->rsn_ie, (void*)ie, 8);
                    ((unsigned short *)buf)[4] = 1;
                    memcpy((void *)(&(((unsigned char *)buf)[10])),(void *)(&(((unsigned char *)buf)[4])), 4);
                    memcpy((void *)(&(((unsigned char *)buf)[14])), (void *)(&(((unsigned char *)buf)[14 + 4 * (CipherCnt - 1)])), len - 8 - (CipherCnt - 1) * 4);
                    len = len - (CipherCnt - 1) * 4;
                }
                else
                {
                    //exist ccmp use it
                    //memcpy((void*)bssp->rsn_ie, (void*)ie, 8);
                    //memcpy((void *)(&(((unsigned char *)bssp->rsn_ie)[4])), (void *)(&(((unsigned char *)ie)[10 + i * 4])), 4);
                    ((unsigned short *)buf)[4] = 1;
                    memcpy((void *)(&(((unsigned char *)buf)[10])),(void *)(&(((unsigned char *)buf)[10 + i * 4])), 4);
                    memcpy((void *)(&(((unsigned char *)buf)[14])), (void *)(&(((unsigned char *)buf)[14 + 4 * (CipherCnt - 1)])), len - 8 - (CipherCnt - 1) * 4);
                    len = len - (CipherCnt - 1) * 4;
                }

                ((unsigned char *)buf)[1] -= (CipherCnt - 1) * 4;
            }
        }   


    }
    #endif
    

    #if 0
    {
        uint32 i;
        
        printf("\n\n\n");            

        for(i = 0; i < len;)
        {
            printf("id = %d\n",*(((uint8 *)buf)+ i));
            i++;                
            len = *(((uint8 *)buf)+ i);
            printf("len = %d\n",len);
            i++;
            len = i + len;
           
            for(; i < len; i++)
            {
                printf("%02x ", *(((uint8 *)buf)+ i));
            }
            
            printf("\n\n\n");
        }
    }
    #endif 

    
    
    
	for (pos = buf, end = pos + len; pos + 1 < end; pos += 2 + pos[1])
    {
		if (pos[0] == 0xdd && ((pos == buf + len - 1) || pos[1] == 0)) 
		{
			/* Ignore padding */
			break;
		}

        if (pos + 2 + pos[1] > end)
        {
			lwip_log("WPA: EAPOL-Key Key Data underflow (ie=%d len=%d pos=%d)\n",
				   pos[0], pos[1], (int) (pos - buf));
			wpa_hexdump_key(MSG_DEBUG, "WPA: Key Data",
					buf, len);
			ret = -1;
			break;
		}

        if (*pos == RSN_INFO_ELEM) 
        {
			ie->rsn_ie = pos;
			ie->rsn_ie_len = pos[1] + 2;
		} 
        else if (*pos == GENERIC_INFO_ELEM)
        {
			ret = wpa_supplicant_parse_generic(pos, end, ie);
			if (ret < 0)
				break;

            if (ret > 0)
            {
				ret = 0;
				break;
			}
		}
        else
	    {
			wpa_hexdump(MSG_DEBUG, "WPA: Unrecognized EAPOL-Key Key Data IE", pos, 2 + pos[1]);
		}
	}

	return ret;
}