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/uuid.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "common/sae.h"
|
||||
#include "crypto/sha256.h"
|
||||
#include "crypto/tls.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);
|
||||
}
|
||||
|
||||
#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=");
|
||||
if (pos2) {
|
||||
if (!end)
|
||||
|
@ -2312,6 +2342,14 @@ static int parse_sae_password(struct hostapd_bss_config *bss, const char *val)
|
|||
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;
|
||||
bss->sae_passwords = pw;
|
||||
|
||||
|
@ -2319,6 +2357,9 @@ static int parse_sae_password(struct hostapd_bss_config *bss, const char *val)
|
|||
fail:
|
||||
str_clear_free(pw->password);
|
||||
os_free(pw->identifier);
|
||||
#ifdef CONFIG_SAE_PK
|
||||
sae_deinit_pk(pw->pk);
|
||||
#endif /* CONFIG_SAE_PK */
|
||||
os_free(pw);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -1776,7 +1776,8 @@ own_ip_addr=127.0.0.1
|
|||
# special meaning of removing all previously added entries.
|
||||
#
|
||||
# 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:
|
||||
#sae_password=secret
|
||||
#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 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 ||
|
||||
!wpa_key_mgmt_sae(conf->wpa_key_mgmt))
|
||||
return 0; /* PT not needed */
|
||||
|
@ -711,6 +712,9 @@ static void hostapd_config_free_sae_passwords(struct hostapd_bss_config *conf)
|
|||
#ifdef CONFIG_SAE
|
||||
sae_deinit_pt(tmp->pt);
|
||||
#endif /* CONFIG_SAE */
|
||||
#ifdef CONFIG_SAE_PK
|
||||
sae_deinit_pk(tmp->pk);
|
||||
#endif /* CONFIG_SAE_PK */
|
||||
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,
|
||||
struct hostapd_config *conf,
|
||||
int full_config)
|
||||
|
@ -1294,6 +1317,15 @@ static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
|
|||
}
|
||||
#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;
|
||||
}
|
||||
|
||||
|
@ -1473,3 +1505,38 @@ int hostapd_sae_pw_id_in_use(struct hostapd_bss_config *conf)
|
|||
return 2;
|
||||
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];
|
||||
int vlan_id;
|
||||
struct sae_pt *pt;
|
||||
struct sae_pk *pk;
|
||||
};
|
||||
|
||||
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,
|
||||
int full_config);
|
||||
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);
|
||||
|
||||
#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) {
|
||||
if (auth_transaction == 1 && sta &&
|
||||
(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,
|
||||
"TESTING: Postpone SAE Commit transmission until Confirm is ready");
|
||||
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;
|
||||
int use_pt = 0;
|
||||
struct sae_pt *pt = NULL;
|
||||
const struct sae_pk *pk = NULL;
|
||||
|
||||
if (sta->sae->tmp) {
|
||||
rx_id = sta->sae->tmp->pw_id;
|
||||
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)
|
||||
use_pt = 1;
|
||||
else if (status_code == WLAN_STATUS_SUCCESS)
|
||||
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;
|
||||
|
||||
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;
|
||||
password = pw->password;
|
||||
pt = pw->pt;
|
||||
if (!(hapd->conf->mesh & MESH_ENABLED))
|
||||
pk = pw->pk;
|
||||
break;
|
||||
}
|
||||
if (!password) {
|
||||
|
@ -515,7 +524,7 @@ static struct wpabuf * auth_build_sae_commit(struct hostapd_data *hapd,
|
|||
|
||||
if (update && use_pt &&
|
||||
sae_prepare_commit_pt(sta->sae, pt, hapd->own_addr, sta->addr,
|
||||
NULL, NULL) < 0)
|
||||
NULL, pk) < 0)
|
||||
return NULL;
|
||||
|
||||
if (update && !use_pt &&
|
||||
|
@ -558,7 +567,10 @@ static struct wpabuf * auth_build_sae_confirm(struct hostapd_data *hapd,
|
|||
if (buf == NULL)
|
||||
return NULL;
|
||||
|
||||
sae_write_confirm(sta->sae, buf);
|
||||
if (sae_write_confirm(sta->sae, buf) < 0) {
|
||||
wpabuf_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
if (!data && sta->sae->tmp && sta->sae->tmp->pw_id)
|
||||
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)
|
||||
return WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
|
||||
status = (sta->sae->tmp && sta->sae->tmp->h2e) ?
|
||||
WLAN_STATUS_SAE_HASH_TO_ELEMENT : WLAN_STATUS_SUCCESS;
|
||||
if (sta->sae->tmp && sta->sae->tmp->pk)
|
||||
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,
|
||||
WLAN_AUTH_SAE, 1,
|
||||
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) {
|
||||
case SAE_NOTHING:
|
||||
if (auth_transaction == 1) {
|
||||
if (sta->sae->tmp)
|
||||
sta->sae->tmp->h2e = status_code ==
|
||||
WLAN_STATUS_SAE_HASH_TO_ELEMENT;
|
||||
if (sta->sae->tmp) {
|
||||
sta->sae->tmp->h2e =
|
||||
(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,
|
||||
!allow_reuse, status_code);
|
||||
if (ret)
|
||||
|
@ -1118,14 +1143,20 @@ static int sae_status_success(struct hostapd_data *hapd, u16 status_code)
|
|||
sae_pwe = 1;
|
||||
else if (id_in_use == 1 && sae_pwe == 0)
|
||||
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) &&
|
||||
status_code == WLAN_STATUS_SUCCESS) ||
|
||||
(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 &&
|
||||
(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,
|
||||
const struct wpabuf *groups)
|
||||
struct sae_data *sae, bool pk)
|
||||
{
|
||||
const struct wpabuf *groups;
|
||||
size_t i, count;
|
||||
const u8 *pos;
|
||||
|
||||
if (!sae->tmp)
|
||||
return 0;
|
||||
groups = sae->tmp->peer_rejected_groups;
|
||||
if (!groups)
|
||||
return 0;
|
||||
|
||||
|
@ -1165,8 +1200,29 @@ static int check_sae_rejected_groups(struct hostapd_data *hapd,
|
|||
group = WPA_GET_LE16(pos);
|
||||
pos += 2;
|
||||
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)
|
||||
return 1;
|
||||
}
|
||||
|
@ -1339,7 +1395,8 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
|
|||
((const u8 *) mgmt) + len -
|
||||
mgmt->u.auth.variable, &token,
|
||||
&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) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"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)
|
||||
goto reply;
|
||||
|
||||
if (sta->sae->tmp &&
|
||||
check_sae_rejected_groups(
|
||||
hapd, sta->sae->tmp->peer_rejected_groups)) {
|
||||
if (check_sae_rejected_groups(hapd, sta->sae,
|
||||
status_code ==
|
||||
WLAN_STATUS_SAE_PK)) {
|
||||
resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
goto reply;
|
||||
}
|
||||
|
@ -1384,7 +1441,8 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
|
|||
MACSTR, MAC2STR(sta->addr));
|
||||
if (sta->sae->tmp)
|
||||
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;
|
||||
data = auth_build_token_req(hapd, sta->sae->group,
|
||||
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)
|
||||
*pos |= 0x10; /* Bit 84 - Beacon Protection Enabled */
|
||||
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 */
|
||||
if (len < 11 && hapd->conf->beacon_prot)
|
||||
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)
|
||||
len = hapd->iface->extended_capa_len;
|
||||
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 *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) ||
|
||||
!wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) ||
|
||||
(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 ||
|
||||
len < 3)
|
||||
return pos;
|
||||
|
@ -1094,7 +1113,12 @@ u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len)
|
|||
*pos++ = 1;
|
||||
/* bits 0-3 = 0 since only one octet of Extended RSN Capabilities is
|
||||
* 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;
|
||||
}
|
||||
|
|
|
@ -256,6 +256,7 @@ struct wpa_auth_config {
|
|||
u8 fils_cache_id[FILS_CACHE_ID_LEN];
|
||||
#endif /* CONFIG_FILS */
|
||||
int sae_pwe;
|
||||
bool sae_pk;
|
||||
int owe_ptk_workaround;
|
||||
u8 transition_disable;
|
||||
#ifdef CONFIG_DPP2
|
||||
|
|
|
@ -198,6 +198,9 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
|
|||
wconf->sae_pwe = 1;
|
||||
else if (sae_pw_id == 1 && wconf->sae_pwe == 0)
|
||||
wconf->sae_pwe = 2;
|
||||
#ifdef CONFIG_SAE_PK
|
||||
wconf->sae_pk = hostapd_sae_pk_in_use(conf);
|
||||
#endif /* CONFIG_SAE_PK */
|
||||
#ifdef CONFIG_OWE
|
||||
wconf->owe_ptk_workaround = conf->owe_ptk_workaround;
|
||||
#endif /* CONFIG_OWE */
|
||||
|
|
|
@ -378,7 +378,7 @@ int wpa_write_rsnxe(struct wpa_auth_config *conf, u8 *buf, size_t len)
|
|||
{
|
||||
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 */
|
||||
|
||||
if (len < 3)
|
||||
|
@ -388,7 +388,12 @@ int wpa_write_rsnxe(struct wpa_auth_config *conf, u8 *buf, size_t len)
|
|||
*pos++ = 1;
|
||||
/* bits 0-3 = 0 since only one octet of Extended RSN Capabilities is
|
||||
* 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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue