static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
						 struct wpa_ssid *ssid,
						 const u8 *bssid)
{
	struct wpabuf *buf;
	size_t len;

	if (ssid->passphrase == NULL) {
		wpa_printf(MSG_DEBUG, "SAE: No password available");
		return NULL;
	}

	if (sme_set_sae_group(wpa_s) < 0) {
		wpa_printf(MSG_DEBUG, "SAE: Failed to select group");
		return NULL;
	}

	if (sae_prepare_commit(wpa_s->own_addr, bssid,
			       (u8 *) ssid->passphrase,
			       os_strlen(ssid->passphrase),
			       &wpa_s->sme.sae) < 0) {
		wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE");
		return NULL;
	}

	len = wpa_s->sme.sae_token ? wpabuf_len(wpa_s->sme.sae_token) : 0;
	buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + len);
	if (buf == NULL)
		return NULL;

	wpabuf_put_le16(buf, 1); /* Transaction seq# */
	wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
	sae_write_commit(&wpa_s->sme.sae, buf, wpa_s->sme.sae_token);

	return buf;
}
static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
			u16 status_code, const u8 *data, size_t len)
{
	int *groups;

	wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE authentication transaction %u "
		"status code %u", auth_transaction, status_code);

	if (auth_transaction == 1 &&
	    status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ &&
	    wpa_s->sme.sae.state == SAE_COMMITTED &&
	    wpa_s->current_bss && wpa_s->current_ssid) {
		int default_groups[] = { 19, 20, 21, 25, 26, 0 };
		u16 group;

		groups = wpa_s->conf->sae_groups;
		if (!groups || groups[0] <= 0)
			groups = default_groups;

		if (len < sizeof(le16)) {
			wpa_dbg(wpa_s, MSG_DEBUG,
				"SME: Too short SAE anti-clogging token request");
			return -1;
		}
		group = WPA_GET_LE16(data);
		wpa_dbg(wpa_s, MSG_DEBUG,
			"SME: SAE anti-clogging token requested (group %u)",
			group);
		if (sae_group_allowed(&wpa_s->sme.sae, groups, group) !=
		    WLAN_STATUS_SUCCESS) {
			wpa_dbg(wpa_s, MSG_ERROR,
				"SME: SAE group %u of anti-clogging request is invalid",
				group);
			return -1;
		}
		wpabuf_free(wpa_s->sme.sae_token);
		wpa_s->sme.sae_token = wpabuf_alloc_copy(data + sizeof(le16),
							 len - sizeof(le16));
		sme_send_authentication(wpa_s, wpa_s->current_bss,
					wpa_s->current_ssid, 1);
		return 0;
	}

	if (auth_transaction == 1 &&
	    status_code == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED &&
	    wpa_s->sme.sae.state == SAE_COMMITTED &&
	    wpa_s->current_bss && wpa_s->current_ssid) {
		wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE group not supported");
		wpa_s->sme.sae_group_index++;
		if (sme_set_sae_group(wpa_s) < 0)
			return -1; /* no other groups enabled */
		wpa_dbg(wpa_s, MSG_DEBUG, "SME: Try next enabled SAE group");
		sme_send_authentication(wpa_s, wpa_s->current_bss,
					wpa_s->current_ssid, 1);
		return 0;
	}

	if (status_code != WLAN_STATUS_SUCCESS)
		return -1;

	if (auth_transaction == 1) {
		groups = wpa_s->conf->sae_groups;

		wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE commit");
		if (wpa_s->current_bss == NULL ||
		    wpa_s->current_ssid == NULL)
			return -1;
		if (wpa_s->sme.sae.state != SAE_COMMITTED)
			return -1;
		if (groups && groups[0] <= 0)
			groups = NULL;
		if (sae_parse_commit(&wpa_s->sme.sae, data, len, NULL, NULL,
				     groups) != WLAN_STATUS_SUCCESS)
			return -1;

		if (sae_process_commit(&wpa_s->sme.sae) < 0) {
			wpa_printf(MSG_DEBUG, "SAE: Failed to process peer "
				   "commit");
			return -1;
		}

		wpabuf_free(wpa_s->sme.sae_token);
		wpa_s->sme.sae_token = NULL;
		sme_send_authentication(wpa_s, wpa_s->current_bss,
					wpa_s->current_ssid, 0);
		return 0;
	} else if (auth_transaction == 2) {
		wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE confirm");
		if (wpa_s->sme.sae.state != SAE_CONFIRMED)
			return -1;
		if (sae_check_confirm(&wpa_s->sme.sae, data, len) < 0)
			return -1;
		wpa_s->sme.sae.state = SAE_ACCEPTED;
		sae_clear_temp_data(&wpa_s->sme.sae);
		return 1;
	}

	return -1;
}
Beispiel #3
0
static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
			u16 status_code, const u8 *data, size_t len)
{
	wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE authentication transaction %u "
		"status code %u", auth_transaction, status_code);

	if (auth_transaction == 1 &&
	    status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ &&
	    wpa_s->sme.sae.state == SAE_COMMITTED &&
	    wpa_s->current_bss && wpa_s->current_ssid) {
		wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE anti-clogging token "
			"requested");
		wpabuf_free(wpa_s->sme.sae_token);
		wpa_s->sme.sae_token = wpabuf_alloc_copy(data, len);
		sme_send_authentication(wpa_s, wpa_s->current_bss,
					wpa_s->current_ssid, 1);
		return 0;
	}

	if (auth_transaction == 1 &&
	    status_code == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED &&
	    wpa_s->sme.sae.state == SAE_COMMITTED &&
	    wpa_s->current_bss && wpa_s->current_ssid) {
		wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE group not supported");
		wpa_s->sme.sae_group_index++;
		if (sme_set_sae_group(wpa_s) < 0)
			return -1; /* no other groups enabled */
		wpa_dbg(wpa_s, MSG_DEBUG, "SME: Try next enabled SAE group");
		sme_send_authentication(wpa_s, wpa_s->current_bss,
					wpa_s->current_ssid, 1);
		return 0;
	}

	if (status_code != WLAN_STATUS_SUCCESS)
		return -1;

	if (auth_transaction == 1) {
		wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE commit");
		if (wpa_s->current_bss == NULL ||
		    wpa_s->current_ssid == NULL)
			return -1;
		if (wpa_s->sme.sae.state != SAE_COMMITTED)
			return -1;
		if (sae_parse_commit(&wpa_s->sme.sae, data, len, NULL, NULL,
				     wpa_s->conf->sae_groups) !=
		    WLAN_STATUS_SUCCESS)
			return -1;

		if (sae_process_commit(&wpa_s->sme.sae) < 0) {
			wpa_printf(MSG_DEBUG, "SAE: Failed to process peer "
				   "commit");
			return -1;
		}

		wpabuf_free(wpa_s->sme.sae_token);
		wpa_s->sme.sae_token = NULL;
		sme_send_authentication(wpa_s, wpa_s->current_bss,
					wpa_s->current_ssid, 0);
		return 0;
	} else if (auth_transaction == 2) {
		wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE confirm");
		if (wpa_s->sme.sae.state != SAE_CONFIRMED)
			return -1;
		if (sae_check_confirm(&wpa_s->sme.sae, data, len) < 0)
			return -1;
		wpa_s->sme.sae.state = SAE_ACCEPTED;
		sae_clear_temp_data(&wpa_s->sme.sae);
		return 1;
	}

	return -1;
}