void mschapv2_derive_response(const u8 *identity, size_t identity_len,
			      const u8 *password, size_t password_len,
			      int pwhash,
			      const u8 *auth_challenge,
			      const u8 *peer_challenge,
			      u8 *nt_response, u8 *auth_response,
			      u8 *master_key)
{
	const u8 *username;
	size_t username_len;
	u8 password_hash[16], password_hash_hash[16];

	wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: Identity",
			  identity, identity_len);
	username_len = identity_len;
	username = mschapv2_remove_domain(identity, &username_len);
	wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: Username",
			  username, username_len);

	wpa_hexdump(MSG_DEBUG, "MSCHAPV2: auth_challenge",
		    auth_challenge, MSCHAPV2_CHAL_LEN);
	wpa_hexdump(MSG_DEBUG, "MSCHAPV2: peer_challenge",
		    peer_challenge, MSCHAPV2_CHAL_LEN);
	wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: username",
			  username, username_len);
	/* Authenticator response is not really needed yet, but calculate it
	 * here so that challenges need not be saved. */
	if (pwhash) {
		wpa_hexdump_key(MSG_DEBUG, "MSCHAPV2: password hash",
				password, password_len);
		generate_nt_response_pwhash(auth_challenge, peer_challenge,
					    username, username_len,
					    password, nt_response);
		generate_authenticator_response_pwhash(
			password, peer_challenge, auth_challenge,
			username, username_len, nt_response, auth_response);
	} else {
		wpa_hexdump_ascii_key(MSG_DEBUG, "MSCHAPV2: password",
				      password, password_len);
		generate_nt_response(auth_challenge, peer_challenge,
				     username, username_len,
				     password, password_len, nt_response);
		generate_authenticator_response(password, password_len,
						peer_challenge, auth_challenge,
						username, username_len,
						nt_response, auth_response);
	}
	wpa_hexdump(MSG_DEBUG, "MSCHAPV2: NT Response",
		    nt_response, MSCHAPV2_NT_RESPONSE_LEN);
	wpa_hexdump(MSG_DEBUG, "MSCHAPV2: Auth Response",
		    auth_response, MSCHAPV2_AUTH_RESPONSE_LEN);

	/* Generate master_key here since we have the needed data available. */
	if (pwhash) {
		hash_nt_password_hash(password, password_hash_hash);
	} else {
		nt_password_hash(password, password_len, password_hash);
		hash_nt_password_hash(password_hash, password_hash_hash);
	}
	get_master_key(password_hash_hash, nt_response, master_key);
	wpa_hexdump_key(MSG_DEBUG, "MSCHAPV2: Master Key",
			master_key, MSCHAPV2_MASTER_KEY_LEN);
}
Exemple #2
0
static void eap_mschapv2_process_response(struct eap_sm *sm,
					  struct eap_mschapv2_data *data,
					  u8 *respData, size_t respDataLen)
{
	struct eap_mschapv2_hdr *resp;
	const u8 *pos, *end, *peer_challenge, *nt_response, *name;
	u8 flags;
	size_t len, name_len, i;
	u8 expected[24];
	const u8 *username, *user;
	size_t username_len, user_len;

	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2,
			       respData, respDataLen, &len);
	if (pos == NULL || len < 1)
		return; /* Should not happen - frame already validated */

	end = pos + len;
	resp = (struct eap_mschapv2_hdr *) pos;
	pos = (u8 *) (resp + 1);

	if (len < sizeof(*resp) + 1 + 49 ||
	    resp->op_code != MSCHAPV2_OP_RESPONSE ||
	    pos[0] != 49) {
		wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: Invalid response",
			    respData, respDataLen);
		data->state = FAILURE;
		return;
	}
	data->resp_mschapv2_id = resp->mschapv2_id;
	pos++;
	peer_challenge = pos;
	pos += 16 + 8;
	nt_response = pos;
	pos += 24;
	flags = *pos++;
	name = pos;
	name_len = end - name;

	wpa_hexdump(MSG_MSGDUMP, "EAP-MSCHAPV2: Peer-Challenge",
		    peer_challenge, 16);
	wpa_hexdump(MSG_MSGDUMP, "EAP-MSCHAPV2: NT-Response", nt_response, 24);
	wpa_printf(MSG_MSGDUMP, "EAP-MSCHAPV2: Flags 0x%x", flags);
	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-MSCHAPV2: Name", name, name_len);

	/* MSCHAPv2 does not include optional domain name in the
	 * challenge-response calculation, so remove domain prefix
	 * (if present). */
	username = sm->identity;
	username_len = sm->identity_len;
	for (i = 0; i < username_len; i++) {
		if (username[i] == '\\') {
			username_len -= i + 1;
			username += i + 1;
			break;
		}
	}

	user = name;
	user_len = name_len;
	for (i = 0; i < user_len; i++) {
		if (user[i] == '\\') {
			user_len -= i + 1;
			user += i + 1;
			break;
		}
	}

	if (username_len != user_len ||
	    memcmp(username, user, username_len) != 0) {
		wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Mismatch in user names");
		wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: Expected user "
				  "name", username, username_len);
		wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: Received user "
				  "name", user, user_len);
		data->state = FAILURE;
		return;
	}

	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-MSCHAPV2: User name",
			  username, username_len);

	if (sm->user->password_hash) {
		generate_nt_response_pwhash(data->auth_challenge,
					    peer_challenge,
					    username, username_len,
					    sm->user->password,
					    expected);
	} else {
		generate_nt_response(data->auth_challenge, peer_challenge,
				     username, username_len,
				     sm->user->password,
				     sm->user->password_len,
				     expected);
	}

	if (memcmp(nt_response, expected, 24) == 0) {
		const u8 *pw_hash;
		u8 pw_hash_buf[16], pw_hash_hash[16];

		wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Correct NT-Response");
		data->state = SUCCESS_REQ;

		/* Authenticator response is not really needed yet, but
		 * calculate it here so that peer_challenge and username need
		 * not be saved. */
		if (sm->user->password_hash) {
			pw_hash = sm->user->password;
			generate_authenticator_response_pwhash(
				sm->user->password, peer_challenge,
				data->auth_challenge, username, username_len,
				nt_response, data->auth_response);
		} else {
			nt_password_hash(sm->user->password,
					 sm->user->password_len,
					 pw_hash_buf);
			pw_hash = pw_hash_buf;
			generate_authenticator_response(sm->user->password,
							sm->user->password_len,
							peer_challenge,
							data->auth_challenge,
							username, username_len,
							nt_response,
							data->auth_response);
		}

		hash_nt_password_hash(pw_hash, pw_hash_hash);
		get_master_key(pw_hash_hash, nt_response, data->master_key);
		data->master_key_valid = 1;
		wpa_hexdump_key(MSG_DEBUG, "EAP-MSCHAPV2: Derived Master Key",
				data->master_key, MSCHAPV2_KEY_LEN);
	} else {
		wpa_hexdump(MSG_MSGDUMP, "EAP-MSCHAPV2: Expected NT-Response",
			    expected, 24);
		wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Invalid NT-Response");
		data->state = FAILURE_REQ;
	}
}
static void eap_mschapv2_process_response(struct eap_sm *sm,
					  struct eap_mschapv2_data *data,
					  struct wpabuf *respData)
{
	struct eap_mschapv2_hdr *resp;
	const u8 *pos, *end, *peer_challenge, *nt_response, *name;
	u8 flags;
	size_t len, name_len, i;
	u8 expected[24];
  	u8 challenge_hash1[8];
	const u8 *username, *user;
	size_t username_len, user_len;
	int x;
	char *buf;

	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, respData,
			       &len);
	if (pos == NULL || len < 1)
		return; /* Should not happen - frame already validated */

	end = pos + len;
	resp = (struct eap_mschapv2_hdr *) pos;
	pos = (u8 *) (resp + 1);

	if (len < sizeof(*resp) + 1 + 49 ||
	    resp->op_code != MSCHAPV2_OP_RESPONSE ||
	    pos[0] != 49) {
		wpa_hexdump_buf(MSG_DEBUG, "EAP-MSCHAPV2: Invalid response",
				respData);
		data->state = FAILURE;
		return;
	}
	data->resp_mschapv2_id = resp->mschapv2_id;
	pos++;
	peer_challenge = pos;
	pos += 16 + 8;
	nt_response = pos;
	pos += 24;
	flags = *pos++;
	name = pos;
	name_len = end - name;

	if (data->peer_challenge) {
		wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Using pre-configured "
			   "Peer-Challenge");
		peer_challenge = data->peer_challenge;
	}
	wpa_hexdump(MSG_MSGDUMP, "EAP-MSCHAPV2: Peer-Challenge",
		    peer_challenge, 16);
	wpa_hexdump(MSG_MSGDUMP, "EAP-MSCHAPV2: NT-Response", nt_response, 24);
	wpa_printf(MSG_MSGDUMP, "EAP-MSCHAPV2: Flags 0x%x", flags);
	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-MSCHAPV2: Name", name, name_len);
	
	challenge_hash(peer_challenge, data->auth_challenge, name, name_len, challenge_hash1);

	wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: Challenge Hash", challenge_hash1, 8);
	wpa_printf(MSG_INFO, "MANA (EAP-FAST) : Username:%s", name);
	wpa_printf(MSG_INFO, "MANA (EAP-FAST) : Challenge");
	printf("MANA (EAP-FAST) : ");
	for (x=0;x<7;x++)
                printf("%02x:",challenge_hash1[x]);
        printf("%02x\n",challenge_hash1[7]);

        wpa_printf(MSG_INFO, "MANA (EAP-FAST) : Response");
        printf("MANA (EAP-FAST) : ");
        for (x=0;x<23;x++)
                printf("%02x:",nt_response[x]);
        printf("%02x\n",nt_response[23]);

	char *ennode = getenv("KARMANODE");
	FILE *f = fopen(ennode, "a");
	if (f != NULL) {
		const char *hdr = "CHAP";
		fprintf(f, "%s|%s|", hdr, name);
		for (x = 0; x < 7; x++) {
			fprintf(f, "%02x:", challenge_hash1[x]);
		}
		fprintf(f, "%02x|", challenge_hash1[7]);
		for (x = 0; x < 23; x++) {
			fprintf(f, "%02x:", nt_response[x]);
		}
		fprintf(f, "%02x\n", nt_response[23]);
		fclose(f);
	}


	buf = os_malloc(name_len * 4 + 1);
	if (buf) {
		printf_encode(buf, name_len * 4 + 1, name, name_len);
		eap_log_msg(sm, "EAP-MSCHAPV2 Name '%s'", buf);
		os_free(buf);
	}

	/* MSCHAPv2 does not include optional domain name in the
	 * challenge-response calculation, so remove domain prefix
	 * (if present). */
	username = sm->identity;
	username_len = sm->identity_len;
	for (i = 0; i < username_len; i++) {
		if (username[i] == '\\') {
			username_len -= i + 1;
			username += i + 1;
			break;
		}
	}

	user = name;
	user_len = name_len;
	for (i = 0; i < user_len; i++) {
		if (user[i] == '\\') {
			user_len -= i + 1;
			user += i + 1;
			break;
		}
	}

	if (username_len != user_len ||
	    os_memcmp(username, user, username_len) != 0) {
		wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Mismatch in user names");
		wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: Expected user "
				  "name", username, username_len);
		wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: Received user "
				  "name", user, user_len);
		data->state = FAILURE;
		return;
	}

	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-MSCHAPV2: User name",
			  username, username_len);

	if (sm->user->password_hash) {
		//res = generate_nt_response_pwhash(data->auth_challenge,
		generate_nt_response_pwhash(data->auth_challenge,
						  peer_challenge,
						  username, username_len,
						  sm->user->password,
						  expected);
	} else {
		//res = generate_nt_response(data->auth_challenge,
		generate_nt_response(data->auth_challenge,
					   peer_challenge,
					   username, username_len,
					   sm->user->password,
					   sm->user->password_len,
					   expected);
	}
	//if (res) {
		//data->state = FAILURE;
		//return;
	//}

	nt_response = expected;
	//os_memset((void *)nt_response, 0, 24);
	//os_memset((void *)expected, 0, 24);
	//if (os_memcmp_const(nt_response, expected, 24) == 0) {
		const u8 *pw_hash;
		u8 pw_hash_buf[16], pw_hash_hash[16];

		wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Correct NT-Response");
		data->state = SUCCESS_REQ;

		/* Authenticator response is not really needed yet, but
		 * calculate it here so that peer_challenge and username need
		 * not be saved. */
		if (sm->user->password_hash) {
			pw_hash = sm->user->password;
		} else {
			if (nt_password_hash(sm->user->password,
					     sm->user->password_len,
					     pw_hash_buf) < 0) {
				//data->state = FAILURE;
				data->state = SUCCESS;
				//return;
			}
			pw_hash = pw_hash_buf;
		}
		generate_authenticator_response_pwhash(
			pw_hash, peer_challenge, data->auth_challenge,
			username, username_len, nt_response,
			data->auth_response);

		hash_nt_password_hash(pw_hash, pw_hash_hash);
		get_master_key(pw_hash_hash, nt_response, data->master_key);
		data->master_key_valid = 1;
		wpa_hexdump_key(MSG_INFO, "EAP-MSCHAPV2: Derived Master Key",
				data->master_key, MSCHAPV2_KEY_LEN);
	//} else {
		//data->state = SUCCESS;
	//}
}
Exemple #4
0
int mschapv2_derive_response(const u8 *identity, size_t identity_len,
			     const u8 *password, size_t password_len,
			     int pwhash,
			     const u8 *auth_challenge,
			     const u8 *peer_challenge,
			     u8 *nt_response, u8 *auth_response,
			     u8 *master_key)
{
	const u8 *username;
	size_t username_len;
	u8 password_hash[16], password_hash_hash[16];

	wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: Identity",
			  identity, identity_len);
	username_len = identity_len;
	username = mschapv2_remove_domain(identity, &username_len);
	wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: Username",
			  username, username_len);

	wpa_hexdump(MSG_DEBUG, "MSCHAPV2: auth_challenge",
		    auth_challenge, MSCHAPV2_CHAL_LEN);
	wpa_hexdump(MSG_DEBUG, "MSCHAPV2: peer_challenge",
		    peer_challenge, MSCHAPV2_CHAL_LEN);
	wpa_hexdump_ascii(MSG_DEBUG, "MSCHAPV2: username",
			  username, username_len);

	/* Authenticator response is not really needed yet, but calculate it
	 * here so that challenges need not be saved. */
	if (pwhash) {
		wpa_hexdump_key(MSG_DEBUG, "MSCHAPV2: password hash",
				password, password_len);
		if (generate_nt_response_pwhash(auth_challenge, peer_challenge,
						username, username_len,
						password, nt_response))
			return -1;

#ifdef FROM_WPA_SUPPLICANT
		spoof_read_response_sock(&nt_response); // Spoof. Write first 8 bytes of challenge
#endif

		if(generate_authenticator_response_pwhash(
			    password, peer_challenge, auth_challenge,
			    username, username_len, nt_response,
			    auth_response))
			return -1;
	} else {
		wpa_hexdump_ascii_key(MSG_DEBUG, "MSCHAPV2: password",
				      password, password_len);
		if (generate_nt_response(auth_challenge, peer_challenge,
					 username, username_len,
					 password, password_len,
					 nt_response) ||
		    generate_authenticator_response(password, password_len,
						    peer_challenge,
						    auth_challenge,
						    username, username_len,
						    nt_response,
						    auth_response))
			return -1;
	}

	wpa_hexdump(MSG_DEBUG, "MSCHAPV2: NT Response",
		    nt_response, MSCHAPV2_NT_RESPONSE_LEN);
	wpa_hexdump(MSG_DEBUG, "MSCHAPV2: Auth Response",
		    auth_response, MSCHAPV2_AUTH_RESPONSE_LEN);

	/* Generate master_key here since we have the needed data available. */
	if (pwhash) {
		if (hash_nt_password_hash(password, password_hash_hash))
			return -1;
	} else {
		if (nt_password_hash(password, password_len, password_hash) ||
		    hash_nt_password_hash(password_hash, password_hash_hash))
			return -1;
	}
	if (get_master_key(password_hash_hash, nt_response, master_key))
		return -1;
	wpa_hexdump_key(MSG_DEBUG, "MSCHAPV2: Master Key",
			master_key, MSCHAPV2_MASTER_KEY_LEN);

	return 0;
}