Esempio n. 1
0
static void * eap_psk_init(struct eap_sm *sm)
{
	struct eap_psk_data *data;
	const u8 *identity, *password;
	size_t identity_len, password_len;

	password = eap_get_config_password(sm, &password_len);
	if (!password || password_len != 16) {
		wpa_printf(MSG_INFO, "EAP-PSK: 16-octet pre-shared key not "
			   "configured");
		return NULL;
	}

	data = os_zalloc(sizeof(*data));
	if (data == NULL)
		return NULL;
	if (eap_psk_key_setup(password, data->ak, data->kdk)) {
		os_free(data);
		return NULL;
	}
	wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: AK", data->ak, EAP_PSK_AK_LEN);
	wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: KDK", data->kdk, EAP_PSK_KDK_LEN);
	data->state = PSK_INIT;

	identity = eap_get_config_identity(sm, &identity_len);
	if (identity) {
		data->id_p = os_malloc(identity_len);
		if (data->id_p)
			os_memcpy(data->id_p, identity, identity_len);
		data->id_p_len = identity_len;
	}
	if (data->id_p == NULL) {
		wpa_printf(MSG_INFO, "EAP-PSK: could not get own identity");
		os_free(data);
		return NULL;
	}

	return data;
}
Esempio n. 2
0
static void eap_psk_process_2(struct eap_sm *sm,
			      struct eap_psk_data *data,
			      struct wpabuf *respData)
{
	const struct eap_psk_hdr_2 *resp;
	u8 *pos, mac[EAP_PSK_MAC_LEN], *buf;
	size_t left, buflen;
	int i;
	const u8 *cpos;

	if (data->state != PSK_1)
		return;

	wpa_printf(MSG_DEBUG, "EAP-PSK: Received PSK-2");

	cpos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, respData,
				&left);
	if (cpos == NULL || left < sizeof(*resp)) {
		wpa_printf(MSG_INFO, "EAP-PSK: Invalid frame");
		return;
	}
	resp = (const struct eap_psk_hdr_2 *) cpos;
	cpos = (const u8 *) (resp + 1);
	left -= sizeof(*resp);

	os_free(data->id_p);
	data->id_p = os_malloc(left);
	if (data->id_p == NULL) {
		wpa_printf(MSG_INFO, "EAP-PSK: Failed to allocate memory for "
			   "ID_P");
		return;
	}
	os_memcpy(data->id_p, cpos, left);
	data->id_p_len = left;
	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-PSK: ID_P",
			  data->id_p, data->id_p_len);

	if (eap_user_get(sm, data->id_p, data->id_p_len, 0) < 0) {
		wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: unknown ID_P",
				  data->id_p, data->id_p_len);
		data->state = FAILURE;
		return;
	}

	for (i = 0;
	     i < EAP_MAX_METHODS &&
		     (sm->user->methods[i].vendor != EAP_VENDOR_IETF ||
		      sm->user->methods[i].method != EAP_TYPE_NONE);
	     i++) {
		if (sm->user->methods[i].vendor == EAP_VENDOR_IETF &&
		    sm->user->methods[i].method == EAP_TYPE_PSK)
			break;
	}

	if (i >= EAP_MAX_METHODS ||
	    sm->user->methods[i].vendor != EAP_VENDOR_IETF ||
	    sm->user->methods[i].method != EAP_TYPE_PSK) {
		wpa_hexdump_ascii(MSG_DEBUG,
				  "EAP-PSK: EAP-PSK not enabled for ID_P",
				  data->id_p, data->id_p_len);
		data->state = FAILURE;
		return;
	}

	if (sm->user->password == NULL ||
	    sm->user->password_len != EAP_PSK_PSK_LEN) {
		wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: invalid password in "
				  "user database for ID_P",
				  data->id_p, data->id_p_len);
		data->state = FAILURE;
		return;
	}
	if (eap_psk_key_setup(sm->user->password, data->ak, data->kdk)) {
		data->state = FAILURE;
		return;
	}
	wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: AK", data->ak, EAP_PSK_AK_LEN);
	wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: KDK", data->kdk, EAP_PSK_KDK_LEN);

	wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: RAND_P (client rand)",
		    resp->rand_p, EAP_PSK_RAND_LEN);
	os_memcpy(data->rand_p, resp->rand_p, EAP_PSK_RAND_LEN);

	/* MAC_P = OMAC1-AES-128(AK, ID_P||ID_S||RAND_S||RAND_P) */
	buflen = data->id_p_len + data->id_s_len + 2 * EAP_PSK_RAND_LEN;
	buf = os_malloc(buflen);
	if (buf == NULL) {
		data->state = FAILURE;
		return;
	}
	os_memcpy(buf, data->id_p, data->id_p_len);
	pos = buf + data->id_p_len;
	os_memcpy(pos, data->id_s, data->id_s_len);
	pos += data->id_s_len;
	os_memcpy(pos, data->rand_s, EAP_PSK_RAND_LEN);
	pos += EAP_PSK_RAND_LEN;
	os_memcpy(pos, data->rand_p, EAP_PSK_RAND_LEN);
	if (omac1_aes_128(data->ak, buf, buflen, mac)) {
		os_free(buf);
		data->state = FAILURE;
		return;
	}
	os_free(buf);
	wpa_hexdump(MSG_DEBUG, "EAP-PSK: MAC_P", resp->mac_p, EAP_PSK_MAC_LEN);
	if (os_memcmp(mac, resp->mac_p, EAP_PSK_MAC_LEN) != 0) {
		wpa_printf(MSG_INFO, "EAP-PSK: Invalid MAC_P");
		wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: Expected MAC_P",
			    mac, EAP_PSK_MAC_LEN);
		data->state = FAILURE;
		return;
	}

	data->state = PSK_3;
}