mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2024-12-01 03:38:21 -05:00
SAE-PK: STA functionality
This adds STA side functionality for SAE-PK. This version enables SAE-PK automatically based on the configured SAE password value if the selected AP advertises support for SAE-PK. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
20ccf97b3d
commit
e7aeb6d8ac
@ -85,16 +85,21 @@ static int sme_set_sae_group(struct wpa_supplicant *wpa_s)
|
|||||||
static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
|
static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
|
||||||
struct wpa_ssid *ssid,
|
struct wpa_ssid *ssid,
|
||||||
const u8 *bssid, int external,
|
const u8 *bssid, int external,
|
||||||
int reuse, int *ret_use_pt)
|
int reuse, int *ret_use_pt,
|
||||||
|
bool *ret_use_pk)
|
||||||
{
|
{
|
||||||
struct wpabuf *buf;
|
struct wpabuf *buf;
|
||||||
size_t len;
|
size_t len;
|
||||||
const char *password;
|
const char *password;
|
||||||
struct wpa_bss *bss;
|
struct wpa_bss *bss;
|
||||||
int use_pt = 0;
|
int use_pt = 0;
|
||||||
|
bool use_pk = false;
|
||||||
|
u8 rsnxe_capa = 0;
|
||||||
|
|
||||||
if (ret_use_pt)
|
if (ret_use_pt)
|
||||||
*ret_use_pt = 0;
|
*ret_use_pt = 0;
|
||||||
|
if (ret_use_pk)
|
||||||
|
*ret_use_pk = false;
|
||||||
|
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
if (wpa_s->sae_commit_override) {
|
if (wpa_s->sae_commit_override) {
|
||||||
@ -124,6 +129,7 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
|
|||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"SAE: Reuse previously generated PWE on a retry with the same AP");
|
"SAE: Reuse previously generated PWE on a retry with the same AP");
|
||||||
use_pt = wpa_s->sme.sae.tmp->h2e;
|
use_pt = wpa_s->sme.sae.tmp->h2e;
|
||||||
|
use_pk = wpa_s->sme.sae.tmp->pk;
|
||||||
goto reuse_data;
|
goto reuse_data;
|
||||||
}
|
}
|
||||||
if (sme_set_sae_group(wpa_s) < 0) {
|
if (sme_set_sae_group(wpa_s) < 0) {
|
||||||
@ -131,19 +137,27 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
|
||||||
|
if (bss) {
|
||||||
|
const u8 *rsnxe;
|
||||||
|
|
||||||
|
rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
|
||||||
|
if (rsnxe && rsnxe[1] >= 1)
|
||||||
|
rsnxe_capa = rsnxe[2];
|
||||||
|
}
|
||||||
|
|
||||||
if (ssid->sae_password_id && wpa_s->conf->sae_pwe != 3)
|
if (ssid->sae_password_id && wpa_s->conf->sae_pwe != 3)
|
||||||
use_pt = 1;
|
use_pt = 1;
|
||||||
|
#ifdef CONFIG_SAE_PK
|
||||||
|
if ((rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_PK)) &&
|
||||||
|
ssid->sae_password && sae_pk_valid_password(ssid->sae_password)) {
|
||||||
|
use_pt = 1;
|
||||||
|
use_pk = true;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
|
|
||||||
if (use_pt || wpa_s->conf->sae_pwe == 1 || wpa_s->conf->sae_pwe == 2) {
|
if (use_pt || wpa_s->conf->sae_pwe == 1 || wpa_s->conf->sae_pwe == 2) {
|
||||||
bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
|
use_pt = !!(rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_H2E));
|
||||||
if (bss) {
|
|
||||||
const u8 *rsnxe;
|
|
||||||
|
|
||||||
rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
|
|
||||||
if (rsnxe && rsnxe[1] >= 1)
|
|
||||||
use_pt = !!(rsnxe[2] &
|
|
||||||
BIT(WLAN_RSNX_CAPAB_SAE_H2E));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((wpa_s->conf->sae_pwe == 1 || ssid->sae_password_id) &&
|
if ((wpa_s->conf->sae_pwe == 1 || ssid->sae_password_id) &&
|
||||||
wpa_s->conf->sae_pwe != 3 &&
|
wpa_s->conf->sae_pwe != 3 &&
|
||||||
@ -167,8 +181,17 @@ static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
|
|||||||
wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE");
|
wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (wpa_s->sme.sae.tmp)
|
if (wpa_s->sme.sae.tmp) {
|
||||||
os_memcpy(wpa_s->sme.sae.tmp->bssid, bssid, ETH_ALEN);
|
os_memcpy(wpa_s->sme.sae.tmp->bssid, bssid, ETH_ALEN);
|
||||||
|
if (use_pt && use_pk)
|
||||||
|
wpa_s->sme.sae.tmp->pk = 1;
|
||||||
|
#ifdef CONFIG_SAE_PK
|
||||||
|
os_memcpy(wpa_s->sme.sae.tmp->own_addr, wpa_s->own_addr,
|
||||||
|
ETH_ALEN);
|
||||||
|
os_memcpy(wpa_s->sme.sae.tmp->peer_addr, bssid, ETH_ALEN);
|
||||||
|
sae_pk_set_password(&wpa_s->sme.sae, password);
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
|
}
|
||||||
|
|
||||||
reuse_data:
|
reuse_data:
|
||||||
len = wpa_s->sme.sae_token ? 3 + wpabuf_len(wpa_s->sme.sae_token) : 0;
|
len = wpa_s->sme.sae_token ? 3 + wpabuf_len(wpa_s->sme.sae_token) : 0;
|
||||||
@ -179,8 +202,12 @@ reuse_data:
|
|||||||
return NULL;
|
return NULL;
|
||||||
if (!external) {
|
if (!external) {
|
||||||
wpabuf_put_le16(buf, 1); /* Transaction seq# */
|
wpabuf_put_le16(buf, 1); /* Transaction seq# */
|
||||||
wpabuf_put_le16(buf, use_pt ? WLAN_STATUS_SAE_HASH_TO_ELEMENT :
|
if (use_pk)
|
||||||
WLAN_STATUS_SUCCESS);
|
wpabuf_put_le16(buf, WLAN_STATUS_SAE_PK);
|
||||||
|
else if (use_pt)
|
||||||
|
wpabuf_put_le16(buf, WLAN_STATUS_SAE_HASH_TO_ELEMENT);
|
||||||
|
else
|
||||||
|
wpabuf_put_le16(buf,WLAN_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
if (sae_write_commit(&wpa_s->sme.sae, buf, wpa_s->sme.sae_token,
|
if (sae_write_commit(&wpa_s->sme.sae, buf, wpa_s->sme.sae_token,
|
||||||
ssid->sae_password_id) < 0) {
|
ssid->sae_password_id) < 0) {
|
||||||
@ -189,6 +216,8 @@ reuse_data:
|
|||||||
}
|
}
|
||||||
if (ret_use_pt)
|
if (ret_use_pt)
|
||||||
*ret_use_pt = use_pt;
|
*ret_use_pt = use_pt;
|
||||||
|
if (ret_use_pk)
|
||||||
|
*ret_use_pk = use_pk;
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
@ -716,7 +745,8 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
|
|||||||
if (start)
|
if (start)
|
||||||
resp = sme_auth_build_sae_commit(wpa_s, ssid,
|
resp = sme_auth_build_sae_commit(wpa_s, ssid,
|
||||||
bss->bssid, 0,
|
bss->bssid, 0,
|
||||||
start == 2, NULL);
|
start == 2, NULL,
|
||||||
|
NULL);
|
||||||
else
|
else
|
||||||
resp = sme_auth_build_sae_confirm(wpa_s, 0);
|
resp = sme_auth_build_sae_confirm(wpa_s, 0);
|
||||||
if (resp == NULL) {
|
if (resp == NULL) {
|
||||||
@ -1008,8 +1038,11 @@ static int sme_external_auth_send_sae_commit(struct wpa_supplicant *wpa_s,
|
|||||||
{
|
{
|
||||||
struct wpabuf *resp, *buf;
|
struct wpabuf *resp, *buf;
|
||||||
int use_pt;
|
int use_pt;
|
||||||
|
bool use_pk;
|
||||||
|
u16 status;
|
||||||
|
|
||||||
resp = sme_auth_build_sae_commit(wpa_s, ssid, bssid, 1, 0, &use_pt);
|
resp = sme_auth_build_sae_commit(wpa_s, ssid, bssid, 1, 0, &use_pt,
|
||||||
|
&use_pk);
|
||||||
if (!resp) {
|
if (!resp) {
|
||||||
wpa_printf(MSG_DEBUG, "SAE: Failed to build SAE commit");
|
wpa_printf(MSG_DEBUG, "SAE: Failed to build SAE commit");
|
||||||
return -1;
|
return -1;
|
||||||
@ -1023,10 +1056,14 @@ static int sme_external_auth_send_sae_commit(struct wpa_supplicant *wpa_s,
|
|||||||
}
|
}
|
||||||
|
|
||||||
wpa_s->sme.seq_num++;
|
wpa_s->sme.seq_num++;
|
||||||
|
if (use_pk)
|
||||||
|
status = WLAN_STATUS_SAE_PK;
|
||||||
|
else if (use_pt)
|
||||||
|
status = WLAN_STATUS_SAE_HASH_TO_ELEMENT;
|
||||||
|
else
|
||||||
|
status = WLAN_STATUS_SUCCESS;
|
||||||
sme_external_auth_build_buf(buf, resp, wpa_s->own_addr,
|
sme_external_auth_build_buf(buf, resp, wpa_s->own_addr,
|
||||||
bssid, 1, wpa_s->sme.seq_num,
|
bssid, 1, wpa_s->sme.seq_num, status);
|
||||||
use_pt ? WLAN_STATUS_SAE_HASH_TO_ELEMENT :
|
|
||||||
WLAN_STATUS_SUCCESS);
|
|
||||||
wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1, 0, 0);
|
wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1, 0, 0);
|
||||||
wpabuf_free(resp);
|
wpabuf_free(resp);
|
||||||
wpabuf_free(buf);
|
wpabuf_free(buf);
|
||||||
@ -1287,7 +1324,8 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (status_code != WLAN_STATUS_SUCCESS &&
|
if (status_code != WLAN_STATUS_SUCCESS &&
|
||||||
status_code != WLAN_STATUS_SAE_HASH_TO_ELEMENT)
|
status_code != WLAN_STATUS_SAE_HASH_TO_ELEMENT &&
|
||||||
|
status_code != WLAN_STATUS_SAE_PK)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (auth_transaction == 1) {
|
if (auth_transaction == 1) {
|
||||||
@ -1310,18 +1348,26 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
|
|||||||
"SAE: Unexpected use of status code 0 in SAE commit when H2E was expected");
|
"SAE: Unexpected use of status code 0 in SAE commit when H2E was expected");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (wpa_s->sme.sae.tmp && !wpa_s->sme.sae.tmp->h2e &&
|
if (wpa_s->sme.sae.tmp &&
|
||||||
|
(!wpa_s->sme.sae.tmp->h2e || wpa_s->sme.sae.tmp->pk) &&
|
||||||
status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT) {
|
status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"SAE: Unexpected use of status code for H2E in SAE commit when H2E was not expected");
|
"SAE: Unexpected use of status code for H2E in SAE commit when H2E was not expected");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (wpa_s->sme.sae.tmp && !wpa_s->sme.sae.tmp->pk &&
|
||||||
|
status_code == WLAN_STATUS_SAE_PK) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"SAE: Unexpected use of status code for PK in SAE commit when PK was not expected");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (groups && groups[0] <= 0)
|
if (groups && groups[0] <= 0)
|
||||||
groups = NULL;
|
groups = NULL;
|
||||||
res = sae_parse_commit(&wpa_s->sme.sae, data, len, NULL, NULL,
|
res = sae_parse_commit(&wpa_s->sme.sae, data, len, NULL, NULL,
|
||||||
groups, status_code ==
|
groups, status_code ==
|
||||||
WLAN_STATUS_SAE_HASH_TO_ELEMENT);
|
WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
|
||||||
|
status_code == WLAN_STATUS_SAE_PK);
|
||||||
if (res == SAE_SILENTLY_DISCARD) {
|
if (res == SAE_SILENTLY_DISCARD) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"SAE: Drop commit message due to reflection attack");
|
"SAE: Drop commit message due to reflection attack");
|
||||||
|
@ -2061,7 +2061,9 @@ static void wpa_s_setup_sae_pt(struct wpa_config *conf, struct wpa_ssid *ssid)
|
|||||||
if (!password)
|
if (!password)
|
||||||
password = ssid->passphrase;
|
password = ssid->passphrase;
|
||||||
|
|
||||||
if ((conf->sae_pwe == 0 && !ssid->sae_password_id) || !password ||
|
if (!password ||
|
||||||
|
(conf->sae_pwe == 0 && !ssid->sae_password_id &&
|
||||||
|
!sae_pk_valid_password(password)) ||
|
||||||
conf->sae_pwe == 3) {
|
conf->sae_pwe == 3) {
|
||||||
/* PT derivation not needed */
|
/* PT derivation not needed */
|
||||||
sae_deinit_pt(ssid->pt);
|
sae_deinit_pt(ssid->pt);
|
||||||
|
Loading…
Reference in New Issue
Block a user