Ejemplo n.º 1
0
static int eapol_test_compare_pmk(struct eapol_test_data *e)
{
	u8 pmk[PMK_LEN];
	int ret = 1;

	if (eapol_sm_get_key(e->wpa_s->eapol, pmk, PMK_LEN) == 0) {
		wpa_hexdump(MSG_DEBUG, "PMK from EAPOL", pmk, PMK_LEN);
		if (os_memcmp(pmk, e->authenticator_pmk, PMK_LEN) != 0) {
			printf("WARNING: PMK mismatch\n");
			wpa_hexdump(MSG_DEBUG, "PMK from AS",
				    e->authenticator_pmk, PMK_LEN);
		} else if (e->radius_access_accept_received)
			ret = 0;
	} else if (e->authenticator_pmk_len == 16 &&
		   eapol_sm_get_key(e->wpa_s->eapol, pmk, 16) == 0) {
		wpa_hexdump(MSG_DEBUG, "LEAP PMK from EAPOL", pmk, 16);
		if (os_memcmp(pmk, e->authenticator_pmk, 16) != 0) {
			printf("WARNING: PMK mismatch\n");
			wpa_hexdump(MSG_DEBUG, "PMK from AS",
				    e->authenticator_pmk, 16);
		} else if (e->radius_access_accept_received)
			ret = 0;
	} else if (e->radius_access_accept_received && e->no_mppe_keys) {
		/* No keying material expected */
		ret = 0;
	}

	if (ret && !e->no_mppe_keys)
		e->num_mppe_mismatch++;
	else if (!e->no_mppe_keys)
		e->num_mppe_ok++;

	return ret;
}
Ejemplo n.º 2
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);

}
Ejemplo n.º 3
0
static int eapol_test_compare_pmk(struct eapol_test_data *e)
{
	u8 pmk[PMK_LEN];
	int ret = 1;
	const u8 *sess_id;
	size_t sess_id_len;

	if (eapol_sm_get_key(e->wpa_s->eapol, pmk, PMK_LEN) == 0) {
		wpa_hexdump(MSG_DEBUG, "PMK from EAPOL", pmk, PMK_LEN);
		if (os_memcmp(pmk, e->authenticator_pmk, PMK_LEN) != 0) {
			printf("WARNING: PMK mismatch\n");
			wpa_hexdump(MSG_DEBUG, "PMK from AS",
				    e->authenticator_pmk, PMK_LEN);
		} else if (e->radius_access_accept_received)
			ret = 0;
	} else if (e->authenticator_pmk_len == 16 &&
		   eapol_sm_get_key(e->wpa_s->eapol, pmk, 16) == 0) {
		wpa_hexdump(MSG_DEBUG, "LEAP PMK from EAPOL", pmk, 16);
		if (os_memcmp(pmk, e->authenticator_pmk, 16) != 0) {
			printf("WARNING: PMK mismatch\n");
			wpa_hexdump(MSG_DEBUG, "PMK from AS",
				    e->authenticator_pmk, 16);
		} else if (e->radius_access_accept_received)
			ret = 0;
	} else if (e->radius_access_accept_received && e->no_mppe_keys) {
		/* No keying material expected */
		ret = 0;
	}

	if (ret && !e->no_mppe_keys)
		e->num_mppe_mismatch++;
	else if (!e->no_mppe_keys)
		e->num_mppe_ok++;

	sess_id = eapol_sm_get_session_id(e->wpa_s->eapol, &sess_id_len);
	if (!sess_id)
		return ret;
	if (e->authenticator_eap_key_name_len == 0) {
		wpa_printf(MSG_INFO, "No EAP-Key-Name received from server");
		return ret;
	}

	if (e->authenticator_eap_key_name_len != sess_id_len ||
	    os_memcmp(e->authenticator_eap_key_name, sess_id, sess_id_len) != 0)
	{
		wpa_printf(MSG_INFO,
			   "Locally derived EAP Session-Id does not match EAP-Key-Name from server");
		wpa_hexdump(MSG_DEBUG, "EAP Session-Id", sess_id, sess_id_len);
		wpa_hexdump(MSG_DEBUG, "EAP-Key-Name from server",
			    e->authenticator_eap_key_name,
			    e->authenticator_eap_key_name_len);
	} else {
		wpa_printf(MSG_INFO,
			   "Locally derived EAP Session-Id matches EAP-Key-Name from server");
	}

	return ret;
}
static void rsn_preauth_eapol_cb(struct eapol_sm *eapol, int success,
				 void *ctx)
{
	struct wpa_sm *sm = ctx;
	u8 pmk[PMK_LEN];

	if (success) {
		int res, pmk_len;
		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 == 0) {
			wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from pre-auth",
					pmk, pmk_len);
			sm->pmk_len = pmk_len;
			pmksa_cache_add(sm->pmksa, pmk, pmk_len,
					sm->preauth_bssid, sm->own_addr,
					sm->network_ctx,
					WPA_KEY_MGMT_IEEE8021X);
		} else {
			wpa_msg(sm->ctx->ctx, MSG_INFO, "RSN: failed to get "
				"master session key from pre-auth EAPOL state "
				"machines");
			success = 0;
		}
	}

	wpa_msg(sm->ctx->ctx, MSG_INFO, "RSN: pre-authentication with " MACSTR
		" %s", MAC2STR(sm->preauth_bssid),
		success ? "completed successfully" : "failed");

	rsn_preauth_deinit(sm);
	rsn_preauth_candidate_process(sm);
}
Ejemplo n.º 5
0
static void rsn_preauth_eapol_cb(struct eapol_sm *eapol, int success,
				 void *ctx)
{
	struct wpa_sm *sm = ctx;
	u8 pmk[PMK_LEN];

	if (success) {
		int res, pmk_len;
		pmk_len = PMK_LEN;
		res = eapol_sm_get_key(eapol, pmk, PMK_LEN);
#ifdef EAP_LEAP
		if (res) {
			res = eapol_sm_get_key(eapol, pmk, 16);
			pmk_len = 16;
		}
#endif /* EAP_LEAP */
		if (res == 0) {
			wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from pre-auth",
					pmk, pmk_len);
			sm->pmk_len = pmk_len;
			pmksa_cache_add(sm, pmk, pmk_len,
					sm->preauth_bssid, sm->own_addr,
					sm->cur_ssid);
		} else {
			wpa_msg(sm->ctx->ctx, MSG_INFO, "RSN: failed to get "
				"master session key from pre-auth EAPOL state "
				"machines");
			success = 0;
		}
	}

	wpa_msg(sm->ctx->ctx, MSG_INFO, "RSN: pre-authentication with " MACSTR
		" %s", MAC2STR(sm->preauth_bssid),
		success ? "completed successfully" : "failed");

	rsn_preauth_deinit(sm);
	rsn_preauth_candidate_process(sm);
}
Ejemplo n.º 6
0
static void eapol_sm_processKey(struct eapol_sm *sm)
{
	struct ieee802_1x_hdr *hdr;
	struct ieee802_1x_eapol_key *key;
	struct eap_key_data keydata;
	u8 orig_key_sign[IEEE8021X_KEY_SIGN_LEN], datakey[32];
	u8 ekey[IEEE8021X_KEY_IV_LEN + IEEE8021X_ENCR_KEY_LEN];
	int key_len, res, sign_key_len, encr_key_len;
	u16 rx_key_length;

	wpa_printf(MSG_DEBUG, "EAPOL: processKey");
	if (sm->last_rx_key == NULL)
		return;

	if (!sm->conf.accept_802_1x_keys) {
		wpa_printf(MSG_WARNING, "EAPOL: Received IEEE 802.1X EAPOL-Key"
			   " even though this was not accepted - "
			   "ignoring this packet");
		return;
	}

	hdr = (struct ieee802_1x_hdr *) sm->last_rx_key;
	key = (struct ieee802_1x_eapol_key *) (hdr + 1);
	if (sizeof(*hdr) + be_to_host16(hdr->length) > sm->last_rx_key_len) {
		wpa_printf(MSG_WARNING, "EAPOL: Too short EAPOL-Key frame");
		return;
	}
	rx_key_length = WPA_GET_BE16(key->key_length);
	wpa_printf(MSG_DEBUG, "EAPOL: RX IEEE 802.1X ver=%d type=%d len=%d "
		   "EAPOL-Key: type=%d key_length=%d key_index=0x%x",
		   hdr->version, hdr->type, be_to_host16(hdr->length),
		   key->type, rx_key_length, key->key_index);

	eapol_sm_notify_lower_layer_success(sm, 1);
	sign_key_len = IEEE8021X_SIGN_KEY_LEN;
	encr_key_len = IEEE8021X_ENCR_KEY_LEN;
	res = eapol_sm_get_key(sm, (u8 *) &keydata, sizeof(keydata));
	if (res < 0) {
		wpa_printf(MSG_DEBUG, "EAPOL: Could not get master key for "
			   "decrypting EAPOL-Key keys");
		return;
	}
	if (res == 16) {
		/* LEAP derives only 16 bytes of keying material. */
		res = eapol_sm_get_key(sm, (u8 *) &keydata, 16);
		if (res) {
			wpa_printf(MSG_DEBUG, "EAPOL: Could not get LEAP "
				   "master key for decrypting EAPOL-Key keys");
			return;
		}
		sign_key_len = 16;
		encr_key_len = 16;
		os_memcpy(keydata.sign_key, keydata.encr_key, 16);
	} else if (res) {
		wpa_printf(MSG_DEBUG, "EAPOL: Could not get enough master key "
			   "data for decrypting EAPOL-Key keys (res=%d)", res);
		return;
	}

	/* The key replay_counter must increase when same master key */
	if (sm->replay_counter_valid &&
	    os_memcmp(sm->last_replay_counter, key->replay_counter,
		      IEEE8021X_REPLAY_COUNTER_LEN) >= 0) {
		wpa_printf(MSG_WARNING, "EAPOL: EAPOL-Key replay counter did "
			   "not increase - ignoring key");
		wpa_hexdump(MSG_DEBUG, "EAPOL: last replay counter",
			    sm->last_replay_counter,
			    IEEE8021X_REPLAY_COUNTER_LEN);
		wpa_hexdump(MSG_DEBUG, "EAPOL: received replay counter",
			    key->replay_counter, IEEE8021X_REPLAY_COUNTER_LEN);
		return;
	}

	/* Verify key signature (HMAC-MD5) */
	os_memcpy(orig_key_sign, key->key_signature, IEEE8021X_KEY_SIGN_LEN);
	os_memset(key->key_signature, 0, IEEE8021X_KEY_SIGN_LEN);
	hmac_md5(keydata.sign_key, sign_key_len,
		 sm->last_rx_key, sizeof(*hdr) + be_to_host16(hdr->length),
		 key->key_signature);
	if (os_memcmp(orig_key_sign, key->key_signature,
		      IEEE8021X_KEY_SIGN_LEN) != 0) {
		wpa_printf(MSG_DEBUG, "EAPOL: Invalid key signature in "
			   "EAPOL-Key packet");
		os_memcpy(key->key_signature, orig_key_sign,
			  IEEE8021X_KEY_SIGN_LEN);
		return;
	}
	wpa_printf(MSG_DEBUG, "EAPOL: EAPOL-Key key signature verified");

	key_len = be_to_host16(hdr->length) - sizeof(*key);
	if (key_len > 32 || rx_key_length > 32) {
		wpa_printf(MSG_WARNING, "EAPOL: Too long key data length %d",
			   key_len ? key_len : rx_key_length);
		return;
	}
	if (key_len == rx_key_length) {
		os_memcpy(ekey, key->key_iv, IEEE8021X_KEY_IV_LEN);
		os_memcpy(ekey + IEEE8021X_KEY_IV_LEN, keydata.encr_key,
			  encr_key_len);
		os_memcpy(datakey, key + 1, key_len);
		rc4_skip(ekey, IEEE8021X_KEY_IV_LEN + encr_key_len, 0,
			 datakey, key_len);
		wpa_hexdump_key(MSG_DEBUG, "EAPOL: Decrypted(RC4) key",
				datakey, key_len);
	} else if (key_len == 0) {
		/*
		 * IEEE 802.1X-2004 specifies that least significant Key Length
		 * octets from MS-MPPE-Send-Key are used as the key if the key
		 * data is not present. This seems to be meaning the beginning
		 * of the MS-MPPE-Send-Key. In addition, MS-MPPE-Send-Key in
		 * Supplicant corresponds to MS-MPPE-Recv-Key in Authenticator.
		 * Anyway, taking the beginning of the keying material from EAP
		 * seems to interoperate with Authenticators.
		 */
		key_len = rx_key_length;
		os_memcpy(datakey, keydata.encr_key, key_len);
		wpa_hexdump_key(MSG_DEBUG, "EAPOL: using part of EAP keying "
				"material data encryption key",
				datakey, key_len);
	} else {
		wpa_printf(MSG_DEBUG, "EAPOL: Invalid key data length %d "
			   "(key_length=%d)", key_len, rx_key_length);
		return;
	}

	sm->replay_counter_valid = TRUE;
	os_memcpy(sm->last_replay_counter, key->replay_counter,
		  IEEE8021X_REPLAY_COUNTER_LEN);

	wpa_printf(MSG_DEBUG, "EAPOL: Setting dynamic WEP key: %s keyidx %d "
		   "len %d",
		   key->key_index & IEEE8021X_KEY_INDEX_FLAG ?
		   "unicast" : "broadcast",
		   key->key_index & IEEE8021X_KEY_INDEX_MASK, key_len);

	if (sm->ctx->set_wep_key &&
	    sm->ctx->set_wep_key(sm->ctx->ctx,
				 key->key_index & IEEE8021X_KEY_INDEX_FLAG,
				 key->key_index & IEEE8021X_KEY_INDEX_MASK,
				 datakey, key_len) < 0) {
		wpa_printf(MSG_WARNING, "EAPOL: Failed to set WEP key to the "
			   " driver.");
	} else {
		if (key->key_index & IEEE8021X_KEY_INDEX_FLAG)
			sm->unicast_key_received = TRUE;
		else
			sm->broadcast_key_received = TRUE;

		if ((sm->unicast_key_received ||
		     !(sm->conf.required_keys & EAPOL_REQUIRE_KEY_UNICAST)) &&
		    (sm->broadcast_key_received ||
		     !(sm->conf.required_keys & EAPOL_REQUIRE_KEY_BROADCAST)))
		{
			wpa_printf(MSG_DEBUG, "EAPOL: all required EAPOL-Key "
				   "frames received");
			sm->portValid = TRUE;
			if (sm->ctx->eapol_done_cb)
				sm->ctx->eapol_done_cb(sm->ctx->ctx);
		}
	}
}
Ejemplo n.º 7
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);

}
Ejemplo n.º 8
0
int main(int argc, char *argv[])
{
	struct wpa_supplicant wpa_s;
	u8 pmk[PMK_LEN];
	int ret = 1;

	if (argc == 2 && strcmp(argv[1], "scard") == 0) {
		return scard_test();
	}

	if (argc < 4) {
		printf("usage: eapol_test <conf> <auth srv IP> <secret>\n");
		return -1;
	}

	eloop_init(&wpa_s);

	memset(&wpa_s, 0, sizeof(wpa_s));
	wpa_s.conf = wpa_config_read(argv[1]);
	if (wpa_s.conf == NULL) {
		printf("Failed to parse configuration file '%s'.\n", argv[1]);
		return -1;
	}
	if (wpa_s.conf->ssid == NULL) {
		printf("No networks defined.\n");
		return -1;
	}

	wpa_init_conf(&wpa_s, argv[2], argv[3]);
	if (wpa_supplicant_ctrl_iface_init(&wpa_s)) {
		printf("Failed to initialize control interface '%s'.\n"
		       "You may have another eapol_test process already "
		       "running or the file was\n"
		       "left by an unclean termination of eapol_test in "
		       "which case you will need\n"
		       "to manually remove this file before starting "
		       "eapol_test again.\n",
		       wpa_s.conf->ctrl_interface);
		return -1;
	}
	wpa_supplicant_scard_init(&wpa_s, wpa_s.conf->ssid);

	if (test_eapol(&wpa_s, wpa_s.conf->ssid))
		return -1;

	eloop_register_timeout(30, 0, eapol_test_timeout, &wpa_s, NULL);
	eloop_register_timeout(0, 0, send_eap_request_identity, &wpa_s, NULL);
	eloop_register_signal(SIGINT, eapol_test_terminate, NULL);
	eloop_register_signal(SIGTERM, eapol_test_terminate, NULL);
	eloop_register_signal(SIGHUP, eapol_test_terminate, NULL);
	eloop_run();

	if (eapol_sm_get_key(wpa_s.eapol, pmk, PMK_LEN) == 0) {
		wpa_hexdump(MSG_DEBUG, "PMK from EAPOL", pmk, PMK_LEN);
		if (memcmp(pmk, wpa_s.authenticator_pmk, PMK_LEN) != 0)
			printf("WARNING: PMK mismatch\n");
		else if (wpa_s.radius_access_accept_received)
			ret = 0;
	} else if (wpa_s.authenticator_pmk_len == 16 &&
		   eapol_sm_get_key(wpa_s.eapol, pmk, 16) == 0) {
		wpa_hexdump(MSG_DEBUG, "LEAP PMK from EAPOL", pmk, 16);
		if (memcmp(pmk, wpa_s.authenticator_pmk, 16) != 0)
			printf("WARNING: PMK mismatch\n");
		else if (wpa_s.radius_access_accept_received)
			ret = 0;
	} else if (wpa_s.radius_access_accept_received && argc > 4) {
		/* No keying material expected */
		ret = 0;
	}

	if (wpa_s.auth_timed_out)
		ret = -2;
	if (wpa_s.radius_access_reject_received)
		ret = -3;

	test_eapol_clean(&wpa_s);

	eloop_destroy();

	return ret;
}
CSCM_EXPORT int eap_supplicant_authenticate (
	u8 *MSK_buffer,
	size_t MSK_buffer_len,
	int wimax_mode,
	int generate_eap_request_identity)
{

	int ret = EAP_SUPPLICANT_STARTED;

	wpa_printf(MSG_DEBUG, "Entering eap_supplicant_authenticate\n");

	// Initialize EAPOL sm and other structures	
	if (test_eapol(&eapol_test, &wpa_s, wpa_s.conf->ssid))
		return EAP_SUPPLICANT_TEST_EAPOL_FAILED;

	wpa_printf(MSG_DEBUG, "After test_eapol\n");
#ifdef UNUSED_CODE
	if (wait_for_monitor)
		wpa_supplicant_ctrl_iface_wait(&wpa_s);
#endif

	p_eapol_test->radius_access_accept_received = 0;
	
	// Set up for authentication
	eloop_clear_terminate();
	eloop_register_timeout(eapol_test.authentication_timeout_sec, 0, 
		eapol_test_timeout, &eapol_test, NULL);
	if (generate_eap_request_identity)
		eloop_register_timeout(0, 0, send_eap_request_identity, &wpa_s, NULL);
	eloop_register_signal(SIGINT, eapol_test_terminate, NULL);
	eloop_register_signal(SIGTERM, eapol_test_terminate, NULL);
#ifndef CONFIG_NATIVE_WINDOWS
	eloop_register_signal(SIGHUP, eapol_test_terminate, NULL);
#endif /* CONFIG_NATIVE_WINDOWS */

	wpa_printf(MSG_DEBUG, "After eloop setup calls\n");

	ieee802_1x_rx_is_ready = 1;
	eloop_run(wimax_mode);
	ieee802_1x_rx_is_ready = 0;

	wpa_printf(MSG_DEBUG, "After eloop_run\n");

	memset(MSK_buffer, 0, MSK_buffer_len);
	if (eapol_test.auth_timed_out)
		ret = EAP_SUPPLICANT_TIMED_OUT;
	else if (eapol_test.radius_access_reject_received)
		ret = EAP_SUPPLICANT_RADIUS_ACCESS_REJECT_RECEIVED;
	else if (wimax_mode) { 
		ret = eapol_sm_get_key(eapol_test.wpa_s->eapol, MSK_buffer, MSK_buffer_len);
		wpa_printf(MSG_DEBUG, "eapol_sm_get_key returned %d\n", ret);
		if (ret)
			ret = EAP_SUPPLICANT_SM_GET_KEY_FAILED;
		else
			ret = EAP_SUPPLICANT_SUCCESS;
		}
	else {
		if (eapol_test_compare_pmk(&eapol_test) == 0 &&
			eapol_sm_get_key(eapol_test.wpa_s->eapol, MSK_buffer, MSK_buffer_len) == 0) 
			ret = EAP_SUPPLICANT_SUCCESS;
		else
			ret = EAP_SUPPLICANT_SM_GET_KEY_FAILED;
		}
	
	if (ret == EAP_SUPPLICANT_SUCCESS)
		{	
		wpa_printf(MSG_DEBUG, "MSK before reordering");
		wpa_hexdump(MSG_DEBUG, "MSK[ 0-15] = ", MSK_buffer +  0, 16);
		wpa_hexdump(MSG_DEBUG, "MSK[16-31] = ", MSK_buffer + 16, 16);
		wpa_hexdump(MSG_DEBUG, "MSK[31-47] = ", MSK_buffer + 32, 16);
		wpa_hexdump(MSG_DEBUG, "MSK[48-63] = ", MSK_buffer + 48, 16);
		wpa_printf(MSG_DEBUG, "MSK len = %d\n", MSK_buffer_len);
		}

	if (!wimax_mode) {
		wpa_printf(MSG_ERROR, "MPPE keys OK: %d  mismatch: %d\n",
			   eapol_test.num_mppe_ok, eapol_test.num_mppe_mismatch);
		if (ret == EAP_SUPPLICANT_SUCCESS && eapol_test.num_mppe_mismatch)
			ret = EAP_SUPPLICANT_NUM_MPPE_MISMATCH;
	}

	if (ret)
		wpa_printf(MSG_ERROR, "FAILURE (ret code = %d)\n", ret);
	else
		wpa_printf(MSG_ERROR, "SUCCESS\n");

	return ret;

}
Ejemplo n.º 10
0
static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
				  const unsigned char *src_addr,
				  const u8 *pmkid)
{
	int abort_cached = 0;

	if (pmkid && !sm->cur_pmksa) {
		/* When using drivers that generate RSN IE, wpa_supplicant may
		 * not have enough time to get the association information
		 * event before receiving this 1/4 message, so try to find a
		 * matching PMKSA cache entry here. */
		sm->cur_pmksa = pmksa_cache_get(sm->pmksa, src_addr, pmkid);
		if (sm->cur_pmksa) {
			wpa_printf(MSG_DEBUG, "RSN: found matching PMKID from "
				   "PMKSA cache");
		} else {
			wpa_printf(MSG_DEBUG, "RSN: no matching PMKID found");
			abort_cached = 1;
		}
	}

	if (pmkid && sm->cur_pmksa &&
	    os_memcmp(pmkid, sm->cur_pmksa->pmkid, PMKID_LEN) == 0) {
		wpa_hexdump(MSG_DEBUG, "RSN: matched PMKID", pmkid, PMKID_LEN);
		wpa_sm_set_pmk_from_pmksa(sm);
		wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from PMKSA cache",
				sm->pmk, sm->pmk_len);
		eapol_sm_notify_cached(sm->eapol);
#ifdef CONFIG_IEEE80211R
		sm->xxkey_len = 0;
#endif /* CONFIG_IEEE80211R */
	} else if (wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt) && sm->eapol) {
		int res, pmk_len;
		pmk_len = PMK_LEN;
		res = eapol_sm_get_key(sm->eapol, sm->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(sm->eapol, sm->pmk, 16);
			pmk_len = 16;
		} else {
#ifdef CONFIG_IEEE80211R
			u8 buf[2 * PMK_LEN];
			if (eapol_sm_get_key(sm->eapol, buf, 2 * PMK_LEN) == 0)
			{
				os_memcpy(sm->xxkey, buf + PMK_LEN, PMK_LEN);
				sm->xxkey_len = PMK_LEN;
				os_memset(buf, 0, sizeof(buf));
			}
#endif /* CONFIG_IEEE80211R */
		}
		if (res == 0) {
			wpa_hexdump_key(MSG_DEBUG, "WPA: PMK from EAPOL state "
					"machines", sm->pmk, pmk_len);
			sm->pmk_len = pmk_len;
			if (sm->proto == WPA_PROTO_RSN) {
				pmksa_cache_add(sm->pmksa, sm->pmk, pmk_len,
						src_addr, sm->own_addr,
						sm->network_ctx, sm->key_mgmt);
			}
			if (!sm->cur_pmksa && pmkid &&
			    pmksa_cache_get(sm->pmksa, src_addr, pmkid)) {
				wpa_printf(MSG_DEBUG, "RSN: the new PMK "
					   "matches with the PMKID");
				abort_cached = 0;
			}
		} else {
			wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
				"WPA: Failed to get master session key from "
				"EAPOL state machines");
			wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
				"WPA: Key handshake aborted");
			if (sm->cur_pmksa) {
				wpa_printf(MSG_DEBUG, "RSN: Cancelled PMKSA "
					   "caching attempt");
				sm->cur_pmksa = NULL;
				abort_cached = 1;
			} else if (!abort_cached) {
				return -1;
			}
		}
	}

	if (abort_cached && wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) {
		/* Send EAPOL-Start to trigger full EAP authentication. */
		u8 *buf;
		size_t buflen;

		wpa_printf(MSG_DEBUG, "RSN: no PMKSA entry found - trigger "
			   "full EAP authentication");
		buf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START,
					 NULL, 0, &buflen, NULL);
		if (buf) {
			wpa_sm_ether_send(sm, sm->bssid, ETH_P_EAPOL,
					  buf, buflen);
			os_free(buf);
			return -2;
		}

		return -1;
	}

	return 0;
}