SAE-PK: AP functionality
This adds AP side functionality for SAE-PK. The new sae_password configuration parameters can now be used to enable SAE-PK mode whenever SAE is enabled. Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
00e4fbdcc5
commit
20ccf97b3d
9 changed files with 228 additions and 25 deletions
|
@ -14,6 +14,7 @@
|
||||||
#include "utils/common.h"
|
#include "utils/common.h"
|
||||||
#include "utils/uuid.h"
|
#include "utils/uuid.h"
|
||||||
#include "common/ieee802_11_defs.h"
|
#include "common/ieee802_11_defs.h"
|
||||||
|
#include "common/sae.h"
|
||||||
#include "crypto/sha256.h"
|
#include "crypto/sha256.h"
|
||||||
#include "crypto/tls.h"
|
#include "crypto/tls.h"
|
||||||
#include "drivers/driver.h"
|
#include "drivers/driver.h"
|
||||||
|
@ -2290,6 +2291,35 @@ static int parse_sae_password(struct hostapd_bss_config *bss, const char *val)
|
||||||
pw->vlan_id = atoi(pos2);
|
pw->vlan_id = atoi(pos2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SAE_PK
|
||||||
|
pos2 = os_strstr(pos, "|pk=");
|
||||||
|
if (pos2) {
|
||||||
|
const char *epos;
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
|
if (!end)
|
||||||
|
end = pos2;
|
||||||
|
pos2 += 4;
|
||||||
|
epos = os_strchr(pos2, '|');
|
||||||
|
if (epos) {
|
||||||
|
tmp = os_malloc(epos - pos2 + 1);
|
||||||
|
if (!tmp)
|
||||||
|
goto fail;
|
||||||
|
os_memcpy(tmp, pos2, epos - pos2);
|
||||||
|
tmp[epos - pos2] = '\0';
|
||||||
|
} else {
|
||||||
|
tmp = os_strdup(pos2);
|
||||||
|
if (!tmp)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
pw->pk = sae_parse_pk(tmp);
|
||||||
|
str_clear_free(tmp);
|
||||||
|
if (!pw->pk)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
|
|
||||||
pos2 = os_strstr(pos, "|id=");
|
pos2 = os_strstr(pos, "|id=");
|
||||||
if (pos2) {
|
if (pos2) {
|
||||||
if (!end)
|
if (!end)
|
||||||
|
@ -2312,6 +2342,14 @@ static int parse_sae_password(struct hostapd_bss_config *bss, const char *val)
|
||||||
pw->password[end - val] = '\0';
|
pw->password[end - val] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SAE_PK
|
||||||
|
if (pw->pk && !sae_pk_valid_password(pw->password)) {
|
||||||
|
wpa_printf(MSG_INFO,
|
||||||
|
"Invalid SAE password for a SAE-PK sae_password entry");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
|
|
||||||
pw->next = bss->sae_passwords;
|
pw->next = bss->sae_passwords;
|
||||||
bss->sae_passwords = pw;
|
bss->sae_passwords = pw;
|
||||||
|
|
||||||
|
@ -2319,6 +2357,9 @@ static int parse_sae_password(struct hostapd_bss_config *bss, const char *val)
|
||||||
fail:
|
fail:
|
||||||
str_clear_free(pw->password);
|
str_clear_free(pw->password);
|
||||||
os_free(pw->identifier);
|
os_free(pw->identifier);
|
||||||
|
#ifdef CONFIG_SAE_PK
|
||||||
|
sae_deinit_pk(pw->pk);
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
os_free(pw);
|
os_free(pw);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1776,7 +1776,8 @@ own_ip_addr=127.0.0.1
|
||||||
# special meaning of removing all previously added entries.
|
# special meaning of removing all previously added entries.
|
||||||
#
|
#
|
||||||
# sae_password uses the following encoding:
|
# sae_password uses the following encoding:
|
||||||
#<password/credential>[|mac=<peer mac>][|vlanid=<VLAN ID>][|id=<identifier>]
|
#<password/credential>[|mac=<peer mac>][|vlanid=<VLAN ID>]
|
||||||
|
#[|pk=<m:ECPrivateKey-base64>][|id=<identifier>]
|
||||||
# Examples:
|
# Examples:
|
||||||
#sae_password=secret
|
#sae_password=secret
|
||||||
#sae_password=really secret|mac=ff:ff:ff:ff:ff:ff
|
#sae_password=really secret|mac=ff:ff:ff:ff:ff:ff
|
||||||
|
|
|
@ -461,7 +461,8 @@ int hostapd_setup_sae_pt(struct hostapd_bss_config *conf)
|
||||||
struct hostapd_ssid *ssid = &conf->ssid;
|
struct hostapd_ssid *ssid = &conf->ssid;
|
||||||
struct sae_password_entry *pw;
|
struct sae_password_entry *pw;
|
||||||
|
|
||||||
if ((conf->sae_pwe == 0 && !hostapd_sae_pw_id_in_use(conf)) ||
|
if ((conf->sae_pwe == 0 && !hostapd_sae_pw_id_in_use(conf) &&
|
||||||
|
!hostapd_sae_pk_in_use(conf)) ||
|
||||||
conf->sae_pwe == 3 ||
|
conf->sae_pwe == 3 ||
|
||||||
!wpa_key_mgmt_sae(conf->wpa_key_mgmt))
|
!wpa_key_mgmt_sae(conf->wpa_key_mgmt))
|
||||||
return 0; /* PT not needed */
|
return 0; /* PT not needed */
|
||||||
|
@ -711,6 +712,9 @@ static void hostapd_config_free_sae_passwords(struct hostapd_bss_config *conf)
|
||||||
#ifdef CONFIG_SAE
|
#ifdef CONFIG_SAE
|
||||||
sae_deinit_pt(tmp->pt);
|
sae_deinit_pt(tmp->pt);
|
||||||
#endif /* CONFIG_SAE */
|
#endif /* CONFIG_SAE */
|
||||||
|
#ifdef CONFIG_SAE_PK
|
||||||
|
sae_deinit_pk(tmp->pk);
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
os_free(tmp);
|
os_free(tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1111,6 +1115,25 @@ const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_SAE_PK
|
||||||
|
static bool hostapd_sae_pk_password_without_pk(struct hostapd_bss_config *bss)
|
||||||
|
{
|
||||||
|
struct sae_password_entry *pw;
|
||||||
|
|
||||||
|
if (bss->ssid.wpa_passphrase &&
|
||||||
|
sae_pk_valid_password(bss->ssid.wpa_passphrase))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (pw = bss->sae_passwords; pw; pw = pw->next) {
|
||||||
|
if (!pw->pk && sae_pk_valid_password(pw->password))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
|
static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
|
||||||
struct hostapd_config *conf,
|
struct hostapd_config *conf,
|
||||||
int full_config)
|
int full_config)
|
||||||
|
@ -1294,6 +1317,15 @@ static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_OCV */
|
#endif /* CONFIG_OCV */
|
||||||
|
|
||||||
|
#ifdef CONFIG_SAE_PK
|
||||||
|
if (full_config && hostapd_sae_pk_in_use(bss) &&
|
||||||
|
hostapd_sae_pk_password_without_pk(bss)) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"SAE-PK: SAE password uses SAE-PK style, but does not have PK configured");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1473,3 +1505,38 @@ int hostapd_sae_pw_id_in_use(struct hostapd_bss_config *conf)
|
||||||
return 2;
|
return 2;
|
||||||
return with_id;
|
return with_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool hostapd_sae_pk_in_use(struct hostapd_bss_config *conf)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_SAE_PK
|
||||||
|
struct sae_password_entry *pw;
|
||||||
|
|
||||||
|
for (pw = conf->sae_passwords; pw; pw = pw->next) {
|
||||||
|
if (pw->pk)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_SAE_PK
|
||||||
|
bool hostapd_sae_pk_exclusively(struct hostapd_bss_config *conf)
|
||||||
|
{
|
||||||
|
bool with_pk = false;
|
||||||
|
struct sae_password_entry *pw;
|
||||||
|
|
||||||
|
if (conf->ssid.wpa_passphrase)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (pw = conf->sae_passwords; pw; pw = pw->next) {
|
||||||
|
if (!pw->pk)
|
||||||
|
return false;
|
||||||
|
with_pk = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return with_pk;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
|
|
|
@ -261,6 +261,7 @@ struct sae_password_entry {
|
||||||
u8 peer_addr[ETH_ALEN];
|
u8 peer_addr[ETH_ALEN];
|
||||||
int vlan_id;
|
int vlan_id;
|
||||||
struct sae_pt *pt;
|
struct sae_pt *pt;
|
||||||
|
struct sae_pk *pk;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dpp_controller_conf {
|
struct dpp_controller_conf {
|
||||||
|
@ -1147,6 +1148,8 @@ int hostapd_config_check(struct hostapd_config *conf, int full_config);
|
||||||
void hostapd_set_security_params(struct hostapd_bss_config *bss,
|
void hostapd_set_security_params(struct hostapd_bss_config *bss,
|
||||||
int full_config);
|
int full_config);
|
||||||
int hostapd_sae_pw_id_in_use(struct hostapd_bss_config *conf);
|
int hostapd_sae_pw_id_in_use(struct hostapd_bss_config *conf);
|
||||||
|
bool hostapd_sae_pk_in_use(struct hostapd_bss_config *conf);
|
||||||
|
bool hostapd_sae_pk_exclusively(struct hostapd_bss_config *conf);
|
||||||
int hostapd_setup_sae_pt(struct hostapd_bss_config *conf);
|
int hostapd_setup_sae_pt(struct hostapd_bss_config *conf);
|
||||||
|
|
||||||
#endif /* HOSTAPD_CONFIG_H */
|
#endif /* HOSTAPD_CONFIG_H */
|
||||||
|
|
|
@ -386,7 +386,8 @@ static int send_auth_reply(struct hostapd_data *hapd, struct sta_info *sta,
|
||||||
auth_alg == WLAN_AUTH_SAE) {
|
auth_alg == WLAN_AUTH_SAE) {
|
||||||
if (auth_transaction == 1 && sta &&
|
if (auth_transaction == 1 && sta &&
|
||||||
(resp == WLAN_STATUS_SUCCESS ||
|
(resp == WLAN_STATUS_SUCCESS ||
|
||||||
resp == WLAN_STATUS_SAE_HASH_TO_ELEMENT)) {
|
resp == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
|
||||||
|
resp == WLAN_STATUS_SAE_PK)) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"TESTING: Postpone SAE Commit transmission until Confirm is ready");
|
"TESTING: Postpone SAE Commit transmission until Confirm is ready");
|
||||||
os_free(sta->sae_postponed_commit);
|
os_free(sta->sae_postponed_commit);
|
||||||
|
@ -478,17 +479,23 @@ static struct wpabuf * auth_build_sae_commit(struct hostapd_data *hapd,
|
||||||
const char *rx_id = NULL;
|
const char *rx_id = NULL;
|
||||||
int use_pt = 0;
|
int use_pt = 0;
|
||||||
struct sae_pt *pt = NULL;
|
struct sae_pt *pt = NULL;
|
||||||
|
const struct sae_pk *pk = NULL;
|
||||||
|
|
||||||
if (sta->sae->tmp) {
|
if (sta->sae->tmp) {
|
||||||
rx_id = sta->sae->tmp->pw_id;
|
rx_id = sta->sae->tmp->pw_id;
|
||||||
use_pt = sta->sae->tmp->h2e;
|
use_pt = sta->sae->tmp->h2e;
|
||||||
|
#ifdef CONFIG_SAE_PK
|
||||||
|
os_memcpy(sta->sae->tmp->own_addr, hapd->own_addr, ETH_ALEN);
|
||||||
|
os_memcpy(sta->sae->tmp->peer_addr, sta->addr, ETH_ALEN);
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rx_id && hapd->conf->sae_pwe != 3)
|
if (rx_id && hapd->conf->sae_pwe != 3)
|
||||||
use_pt = 1;
|
use_pt = 1;
|
||||||
else if (status_code == WLAN_STATUS_SUCCESS)
|
else if (status_code == WLAN_STATUS_SUCCESS)
|
||||||
use_pt = 0;
|
use_pt = 0;
|
||||||
else if (status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT)
|
else if (status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
|
||||||
|
status_code == WLAN_STATUS_SAE_PK)
|
||||||
use_pt = 1;
|
use_pt = 1;
|
||||||
|
|
||||||
for (pw = hapd->conf->sae_passwords; pw; pw = pw->next) {
|
for (pw = hapd->conf->sae_passwords; pw; pw = pw->next) {
|
||||||
|
@ -502,6 +509,8 @@ static struct wpabuf * auth_build_sae_commit(struct hostapd_data *hapd,
|
||||||
continue;
|
continue;
|
||||||
password = pw->password;
|
password = pw->password;
|
||||||
pt = pw->pt;
|
pt = pw->pt;
|
||||||
|
if (!(hapd->conf->mesh & MESH_ENABLED))
|
||||||
|
pk = pw->pk;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!password) {
|
if (!password) {
|
||||||
|
@ -515,7 +524,7 @@ static struct wpabuf * auth_build_sae_commit(struct hostapd_data *hapd,
|
||||||
|
|
||||||
if (update && use_pt &&
|
if (update && use_pt &&
|
||||||
sae_prepare_commit_pt(sta->sae, pt, hapd->own_addr, sta->addr,
|
sae_prepare_commit_pt(sta->sae, pt, hapd->own_addr, sta->addr,
|
||||||
NULL, NULL) < 0)
|
NULL, pk) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (update && !use_pt &&
|
if (update && !use_pt &&
|
||||||
|
@ -558,7 +567,10 @@ static struct wpabuf * auth_build_sae_confirm(struct hostapd_data *hapd,
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
sae_write_confirm(sta->sae, buf);
|
if (sae_write_confirm(sta->sae, buf) < 0) {
|
||||||
|
wpabuf_free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
@ -575,11 +587,19 @@ static int auth_sae_send_commit(struct hostapd_data *hapd,
|
||||||
data = auth_build_sae_commit(hapd, sta, update, status_code);
|
data = auth_build_sae_commit(hapd, sta, update, status_code);
|
||||||
if (!data && sta->sae->tmp && sta->sae->tmp->pw_id)
|
if (!data && sta->sae->tmp && sta->sae->tmp->pw_id)
|
||||||
return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER;
|
return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER;
|
||||||
|
#ifdef CONFIG_SAE_PK
|
||||||
|
if (!data && sta->sae->tmp && sta->sae->tmp->reject_group)
|
||||||
|
return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
|
||||||
status = (sta->sae->tmp && sta->sae->tmp->h2e) ?
|
if (sta->sae->tmp && sta->sae->tmp->pk)
|
||||||
WLAN_STATUS_SAE_HASH_TO_ELEMENT : WLAN_STATUS_SUCCESS;
|
status = WLAN_STATUS_SAE_PK;
|
||||||
|
else if (sta->sae->tmp && sta->sae->tmp->h2e)
|
||||||
|
status = WLAN_STATUS_SAE_HASH_TO_ELEMENT;
|
||||||
|
else
|
||||||
|
status = WLAN_STATUS_SUCCESS;
|
||||||
reply_res = send_auth_reply(hapd, sta, sta->addr, bssid,
|
reply_res = send_auth_reply(hapd, sta, sta->addr, bssid,
|
||||||
WLAN_AUTH_SAE, 1,
|
WLAN_AUTH_SAE, 1,
|
||||||
status, wpabuf_head(data),
|
status, wpabuf_head(data),
|
||||||
|
@ -900,9 +920,14 @@ static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
|
||||||
switch (sta->sae->state) {
|
switch (sta->sae->state) {
|
||||||
case SAE_NOTHING:
|
case SAE_NOTHING:
|
||||||
if (auth_transaction == 1) {
|
if (auth_transaction == 1) {
|
||||||
if (sta->sae->tmp)
|
if (sta->sae->tmp) {
|
||||||
sta->sae->tmp->h2e = status_code ==
|
sta->sae->tmp->h2e =
|
||||||
WLAN_STATUS_SAE_HASH_TO_ELEMENT;
|
(status_code ==
|
||||||
|
WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
|
||||||
|
status_code == WLAN_STATUS_SAE_PK);
|
||||||
|
sta->sae->tmp->pk =
|
||||||
|
status_code == WLAN_STATUS_SAE_PK;
|
||||||
|
}
|
||||||
ret = auth_sae_send_commit(hapd, sta, bssid,
|
ret = auth_sae_send_commit(hapd, sta, bssid,
|
||||||
!allow_reuse, status_code);
|
!allow_reuse, status_code);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -1118,14 +1143,20 @@ static int sae_status_success(struct hostapd_data *hapd, u16 status_code)
|
||||||
sae_pwe = 1;
|
sae_pwe = 1;
|
||||||
else if (id_in_use == 1 && sae_pwe == 0)
|
else if (id_in_use == 1 && sae_pwe == 0)
|
||||||
sae_pwe = 2;
|
sae_pwe = 2;
|
||||||
|
#ifdef CONFIG_SAE_PK
|
||||||
|
if (sae_pwe == 0 && hostapd_sae_pk_in_use(hapd->conf))
|
||||||
|
sae_pwe = 2;
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
|
|
||||||
return ((sae_pwe == 0 || sae_pwe == 3) &&
|
return ((sae_pwe == 0 || sae_pwe == 3) &&
|
||||||
status_code == WLAN_STATUS_SUCCESS) ||
|
status_code == WLAN_STATUS_SUCCESS) ||
|
||||||
(sae_pwe == 1 &&
|
(sae_pwe == 1 &&
|
||||||
status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT) ||
|
(status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
|
||||||
|
status_code == WLAN_STATUS_SAE_PK)) ||
|
||||||
(sae_pwe == 2 &&
|
(sae_pwe == 2 &&
|
||||||
(status_code == WLAN_STATUS_SUCCESS ||
|
(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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1148,11 +1179,15 @@ static int sae_is_group_enabled(struct hostapd_data *hapd, int group)
|
||||||
|
|
||||||
|
|
||||||
static int check_sae_rejected_groups(struct hostapd_data *hapd,
|
static int check_sae_rejected_groups(struct hostapd_data *hapd,
|
||||||
const struct wpabuf *groups)
|
struct sae_data *sae, bool pk)
|
||||||
{
|
{
|
||||||
|
const struct wpabuf *groups;
|
||||||
size_t i, count;
|
size_t i, count;
|
||||||
const u8 *pos;
|
const u8 *pos;
|
||||||
|
|
||||||
|
if (!sae->tmp)
|
||||||
|
return 0;
|
||||||
|
groups = sae->tmp->peer_rejected_groups;
|
||||||
if (!groups)
|
if (!groups)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1165,8 +1200,29 @@ static int check_sae_rejected_groups(struct hostapd_data *hapd,
|
||||||
group = WPA_GET_LE16(pos);
|
group = WPA_GET_LE16(pos);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
enabled = sae_is_group_enabled(hapd, group);
|
enabled = sae_is_group_enabled(hapd, group);
|
||||||
wpa_printf(MSG_DEBUG, "SAE: Rejected group %u is %s",
|
|
||||||
group, enabled ? "enabled" : "disabled");
|
#ifdef CONFIG_SAE_PK
|
||||||
|
/* TODO: Could check more explicitly against the matching
|
||||||
|
* sae_password entry only for the somewhat theoretical case of
|
||||||
|
* different passwords using different groups for SAE-PK K_AP
|
||||||
|
* values. */
|
||||||
|
if (pk) {
|
||||||
|
struct sae_password_entry *pw;
|
||||||
|
|
||||||
|
enabled = false;
|
||||||
|
for (pw = hapd->conf->sae_passwords; pw;
|
||||||
|
pw = pw->next) {
|
||||||
|
if (pw->pk && pw->pk->group == group) {
|
||||||
|
enabled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "SAE: Rejected group %u is %s%s",
|
||||||
|
group, enabled ? "enabled" : "disabled",
|
||||||
|
pk ? " (PK)" : "");
|
||||||
if (enabled)
|
if (enabled)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1339,7 +1395,8 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
|
||||||
((const u8 *) mgmt) + len -
|
((const u8 *) mgmt) + len -
|
||||||
mgmt->u.auth.variable, &token,
|
mgmt->u.auth.variable, &token,
|
||||||
&token_len, groups, status_code ==
|
&token_len, groups, status_code ==
|
||||||
WLAN_STATUS_SAE_HASH_TO_ELEMENT);
|
WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
|
||||||
|
status_code == WLAN_STATUS_SAE_PK);
|
||||||
if (resp == SAE_SILENTLY_DISCARD) {
|
if (resp == SAE_SILENTLY_DISCARD) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"SAE: Drop commit message from " MACSTR " due to reflection attack",
|
"SAE: Drop commit message from " MACSTR " due to reflection attack",
|
||||||
|
@ -1369,9 +1426,9 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
|
||||||
if (resp != WLAN_STATUS_SUCCESS)
|
if (resp != WLAN_STATUS_SUCCESS)
|
||||||
goto reply;
|
goto reply;
|
||||||
|
|
||||||
if (sta->sae->tmp &&
|
if (check_sae_rejected_groups(hapd, sta->sae,
|
||||||
check_sae_rejected_groups(
|
status_code ==
|
||||||
hapd, sta->sae->tmp->peer_rejected_groups)) {
|
WLAN_STATUS_SAE_PK)) {
|
||||||
resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
goto reply;
|
goto reply;
|
||||||
}
|
}
|
||||||
|
@ -1384,7 +1441,8 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
|
||||||
MACSTR, MAC2STR(sta->addr));
|
MACSTR, MAC2STR(sta->addr));
|
||||||
if (sta->sae->tmp)
|
if (sta->sae->tmp)
|
||||||
h2e = sta->sae->tmp->h2e;
|
h2e = sta->sae->tmp->h2e;
|
||||||
if (status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT)
|
if (status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
|
||||||
|
status_code == WLAN_STATUS_SAE_PK)
|
||||||
h2e = 1;
|
h2e = 1;
|
||||||
data = auth_build_token_req(hapd, sta->sae->group,
|
data = auth_build_token_req(hapd, sta->sae->group,
|
||||||
sta->addr, h2e);
|
sta->addr, h2e);
|
||||||
|
|
|
@ -427,6 +427,14 @@ static void hostapd_ext_capab_byte(struct hostapd_data *hapd, u8 *pos, int idx)
|
||||||
if (hapd->conf->beacon_prot)
|
if (hapd->conf->beacon_prot)
|
||||||
*pos |= 0x10; /* Bit 84 - Beacon Protection Enabled */
|
*pos |= 0x10; /* Bit 84 - Beacon Protection Enabled */
|
||||||
break;
|
break;
|
||||||
|
case 11: /* Bits 88-95 */
|
||||||
|
#ifdef CONFIG_SAE_PK
|
||||||
|
if (hapd->conf->wpa &&
|
||||||
|
wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
|
||||||
|
hostapd_sae_pk_exclusively(hapd->conf))
|
||||||
|
*pos |= 0x01; /* Bit 88 - SAE PK Exclusively */
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,6 +495,12 @@ u8 * hostapd_eid_ext_capab(struct hostapd_data *hapd, u8 *eid)
|
||||||
#endif /* CONFIG_SAE */
|
#endif /* CONFIG_SAE */
|
||||||
if (len < 11 && hapd->conf->beacon_prot)
|
if (len < 11 && hapd->conf->beacon_prot)
|
||||||
len = 11;
|
len = 11;
|
||||||
|
#ifdef CONFIG_SAE_PK
|
||||||
|
if (len < 12 && hapd->conf->wpa &&
|
||||||
|
wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
|
||||||
|
hostapd_sae_pk_exclusively(hapd->conf))
|
||||||
|
len = 12;
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
if (len < hapd->iface->extended_capa_len)
|
if (len < hapd->iface->extended_capa_len)
|
||||||
len = hapd->iface->extended_capa_len;
|
len = hapd->iface->extended_capa_len;
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
|
@ -1081,11 +1095,16 @@ int get_tx_parameters(struct sta_info *sta, int ap_max_chanwidth,
|
||||||
u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len)
|
u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len)
|
||||||
{
|
{
|
||||||
u8 *pos = eid;
|
u8 *pos = eid;
|
||||||
|
bool sae_pk = false;
|
||||||
|
|
||||||
|
#ifdef CONFIG_SAE_PK
|
||||||
|
sae_pk = hostapd_sae_pk_in_use(hapd->conf);
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
|
|
||||||
if (!(hapd->conf->wpa & WPA_PROTO_RSN) ||
|
if (!(hapd->conf->wpa & WPA_PROTO_RSN) ||
|
||||||
!wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) ||
|
!wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) ||
|
||||||
(hapd->conf->sae_pwe != 1 && hapd->conf->sae_pwe != 2 &&
|
(hapd->conf->sae_pwe != 1 && hapd->conf->sae_pwe != 2 &&
|
||||||
!hostapd_sae_pw_id_in_use(hapd->conf)) ||
|
!hostapd_sae_pw_id_in_use(hapd->conf) && !sae_pk) ||
|
||||||
hapd->conf->sae_pwe == 3 ||
|
hapd->conf->sae_pwe == 3 ||
|
||||||
len < 3)
|
len < 3)
|
||||||
return pos;
|
return pos;
|
||||||
|
@ -1094,7 +1113,12 @@ u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len)
|
||||||
*pos++ = 1;
|
*pos++ = 1;
|
||||||
/* bits 0-3 = 0 since only one octet of Extended RSN Capabilities is
|
/* bits 0-3 = 0 since only one octet of Extended RSN Capabilities is
|
||||||
* used for now */
|
* used for now */
|
||||||
*pos++ = BIT(WLAN_RSNX_CAPAB_SAE_H2E);
|
*pos = BIT(WLAN_RSNX_CAPAB_SAE_H2E);
|
||||||
|
#ifdef CONFIG_SAE_PK
|
||||||
|
if (sae_pk)
|
||||||
|
*pos |= BIT(WLAN_RSNX_CAPAB_SAE_PK);
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
|
pos++;
|
||||||
|
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
|
@ -256,6 +256,7 @@ struct wpa_auth_config {
|
||||||
u8 fils_cache_id[FILS_CACHE_ID_LEN];
|
u8 fils_cache_id[FILS_CACHE_ID_LEN];
|
||||||
#endif /* CONFIG_FILS */
|
#endif /* CONFIG_FILS */
|
||||||
int sae_pwe;
|
int sae_pwe;
|
||||||
|
bool sae_pk;
|
||||||
int owe_ptk_workaround;
|
int owe_ptk_workaround;
|
||||||
u8 transition_disable;
|
u8 transition_disable;
|
||||||
#ifdef CONFIG_DPP2
|
#ifdef CONFIG_DPP2
|
||||||
|
|
|
@ -198,6 +198,9 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
|
||||||
wconf->sae_pwe = 1;
|
wconf->sae_pwe = 1;
|
||||||
else if (sae_pw_id == 1 && wconf->sae_pwe == 0)
|
else if (sae_pw_id == 1 && wconf->sae_pwe == 0)
|
||||||
wconf->sae_pwe = 2;
|
wconf->sae_pwe = 2;
|
||||||
|
#ifdef CONFIG_SAE_PK
|
||||||
|
wconf->sae_pk = hostapd_sae_pk_in_use(conf);
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
#ifdef CONFIG_OWE
|
#ifdef CONFIG_OWE
|
||||||
wconf->owe_ptk_workaround = conf->owe_ptk_workaround;
|
wconf->owe_ptk_workaround = conf->owe_ptk_workaround;
|
||||||
#endif /* CONFIG_OWE */
|
#endif /* CONFIG_OWE */
|
||||||
|
|
|
@ -378,7 +378,7 @@ int wpa_write_rsnxe(struct wpa_auth_config *conf, u8 *buf, size_t len)
|
||||||
{
|
{
|
||||||
u8 *pos = buf;
|
u8 *pos = buf;
|
||||||
|
|
||||||
if (conf->sae_pwe != 1 && conf->sae_pwe != 2)
|
if (conf->sae_pwe != 1 && conf->sae_pwe != 2 && !conf->sae_pk)
|
||||||
return 0; /* no supported extended RSN capabilities */
|
return 0; /* no supported extended RSN capabilities */
|
||||||
|
|
||||||
if (len < 3)
|
if (len < 3)
|
||||||
|
@ -388,7 +388,12 @@ int wpa_write_rsnxe(struct wpa_auth_config *conf, u8 *buf, size_t len)
|
||||||
*pos++ = 1;
|
*pos++ = 1;
|
||||||
/* bits 0-3 = 0 since only one octet of Extended RSN Capabilities is
|
/* bits 0-3 = 0 since only one octet of Extended RSN Capabilities is
|
||||||
* used for now */
|
* used for now */
|
||||||
*pos++ = BIT(WLAN_RSNX_CAPAB_SAE_H2E);
|
*pos = BIT(WLAN_RSNX_CAPAB_SAE_H2E);
|
||||||
|
#ifdef CONFIG_SAE_PK
|
||||||
|
if (conf->sae_pk)
|
||||||
|
*pos |= BIT(WLAN_RSNX_CAPAB_SAE_PK);
|
||||||
|
#endif /* CONFIG_SAE_PK */
|
||||||
|
pos++;
|
||||||
|
|
||||||
return pos - buf;
|
return pos - buf;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue