PASN: Support PASN with SAE key derivation
Signed-off-by: Ilan Peer <ilan.peer@intel.com>
This commit is contained in:
parent
cd2a0a84ce
commit
a93ec28d10
7 changed files with 274 additions and 9 deletions
|
@ -5194,3 +5194,14 @@ void wpa_sm_set_dpp_z(struct wpa_sm *sm, const struct wpabuf *z)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_DPP2 */
|
#endif /* CONFIG_DPP2 */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_PASN
|
||||||
|
void wpa_pasn_pmksa_cache_add(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len,
|
||||||
|
const u8 *pmkid, const u8 *bssid, int key_mgmt)
|
||||||
|
{
|
||||||
|
sm->cur_pmksa = pmksa_cache_add(sm->pmksa, pmk, pmk_len, pmkid, NULL, 0,
|
||||||
|
bssid, sm->own_addr, NULL,
|
||||||
|
key_mgmt, 0);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_PASN */
|
||||||
|
|
|
@ -521,5 +521,7 @@ int owe_process_assoc_resp(struct wpa_sm *sm, const u8 *bssid,
|
||||||
void wpa_sm_set_reset_fils_completed(struct wpa_sm *sm, int set);
|
void wpa_sm_set_reset_fils_completed(struct wpa_sm *sm, int set);
|
||||||
void wpa_sm_set_fils_cache_id(struct wpa_sm *sm, const u8 *fils_cache_id);
|
void wpa_sm_set_fils_cache_id(struct wpa_sm *sm, const u8 *fils_cache_id);
|
||||||
void wpa_sm_set_dpp_z(struct wpa_sm *sm, const struct wpabuf *z);
|
void wpa_sm_set_dpp_z(struct wpa_sm *sm, const struct wpabuf *z);
|
||||||
|
void wpa_pasn_pmksa_cache_add(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len,
|
||||||
|
const u8 *pmkid, const u8 *bssid, int key_mgmt);
|
||||||
|
|
||||||
#endif /* WPA_H */
|
#endif /* WPA_H */
|
||||||
|
|
|
@ -10464,6 +10464,7 @@ static int wpas_ctrl_iface_pasn_start(struct wpa_supplicant *wpa_s, char *cmd)
|
||||||
u8 bssid[ETH_ALEN];
|
u8 bssid[ETH_ALEN];
|
||||||
int akmp = -1, cipher = -1, got_bssid = 0;
|
int akmp = -1, cipher = -1, got_bssid = 0;
|
||||||
u16 group = 0xFFFF;
|
u16 group = 0xFFFF;
|
||||||
|
int id = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Entry format: bssid=<BSSID> akmp=<AKMP> cipher=<CIPHER> group=<group>
|
* Entry format: bssid=<BSSID> akmp=<AKMP> cipher=<CIPHER> group=<group>
|
||||||
|
@ -10503,6 +10504,8 @@ static int wpas_ctrl_iface_pasn_start(struct wpa_supplicant *wpa_s, char *cmd)
|
||||||
cipher = WPA_CIPHER_GCMP;
|
cipher = WPA_CIPHER_GCMP;
|
||||||
} else if (os_strncmp(token, "group=", 6) == 0) {
|
} else if (os_strncmp(token, "group=", 6) == 0) {
|
||||||
group = atoi(token + 6);
|
group = atoi(token + 6);
|
||||||
|
} else if (os_strncmp(token, "nid=", 4) == 0) {
|
||||||
|
id = atoi(token + 4);
|
||||||
} else {
|
} else {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"CTRL: PASN Invalid parameter: '%s'",
|
"CTRL: PASN Invalid parameter: '%s'",
|
||||||
|
@ -10516,7 +10519,7 @@ static int wpas_ctrl_iface_pasn_start(struct wpa_supplicant *wpa_s, char *cmd)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return wpas_pasn_auth_start(wpa_s, bssid, akmp, cipher, group);
|
return wpas_pasn_auth_start(wpa_s, bssid, akmp, cipher, group, id);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_PASN */
|
#endif /* CONFIG_PASN */
|
||||||
|
|
||||||
|
|
|
@ -387,6 +387,11 @@ void wpas_notify_network_removed(struct wpa_supplicant *wpa_s,
|
||||||
wpas_notify_persistent_group_removed(wpa_s, ssid);
|
wpas_notify_persistent_group_removed(wpa_s, ssid);
|
||||||
|
|
||||||
wpas_p2p_network_removed(wpa_s, ssid);
|
wpas_p2p_network_removed(wpa_s, ssid);
|
||||||
|
|
||||||
|
#ifdef CONFIG_PASN
|
||||||
|
if (wpa_s->pasn.ssid == ssid)
|
||||||
|
wpa_s->pasn.ssid = NULL;
|
||||||
|
#endif /* CONFIG_PASN */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "wpa_supplicant_i.h"
|
#include "wpa_supplicant_i.h"
|
||||||
#include "driver_i.h"
|
#include "driver_i.h"
|
||||||
#include "bss.h"
|
#include "bss.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
static const int dot11RSNAConfigPMKLifetime = 43200;
|
static const int dot11RSNAConfigPMKLifetime = 43200;
|
||||||
|
|
||||||
|
@ -29,6 +30,7 @@ struct wpa_pasn_auth_work {
|
||||||
int akmp;
|
int akmp;
|
||||||
int cipher;
|
int cipher;
|
||||||
u16 group;
|
u16 group;
|
||||||
|
int network_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,13 +63,203 @@ static void wpas_pasn_auth_status(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct wpabuf * wpas_pasn_get_wrapped_data(struct wpas_pasn *pasn)
|
#ifdef CONFIG_SAE
|
||||||
|
|
||||||
|
static struct wpabuf * wpas_pasn_wd_sae_commit(struct wpa_supplicant *wpa_s)
|
||||||
{
|
{
|
||||||
|
struct wpas_pasn *pasn = &wpa_s->pasn;
|
||||||
|
struct wpabuf *buf = NULL;
|
||||||
|
const char *password = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (pasn->ssid) {
|
||||||
|
password = pasn->ssid->sae_password;
|
||||||
|
if (!password)
|
||||||
|
password = pasn->ssid->passphrase;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!password) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: SAE without a password");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = sae_set_group(&pasn->sae, pasn->group);
|
||||||
|
if (ret) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: Failed to set SAE group");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: SAE H2E */
|
||||||
|
ret = sae_prepare_commit(wpa_s->own_addr, pasn->bssid,
|
||||||
|
(const u8 *) password, os_strlen(password), 0,
|
||||||
|
&pasn->sae);
|
||||||
|
if (ret) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: Failed to prepare SAE commit");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Need to add the entire Authentication frame body */
|
||||||
|
buf = wpabuf_alloc(6 + SAE_COMMIT_MAX_LEN);
|
||||||
|
if (!buf) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: Failed to allocate SAE buffer");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpabuf_put_le16(buf, WLAN_AUTH_SAE);
|
||||||
|
wpabuf_put_le16(buf, 1);
|
||||||
|
wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
|
||||||
|
|
||||||
|
sae_write_commit(&pasn->sae, buf, NULL, 0);
|
||||||
|
pasn->sae.state = SAE_COMMITTED;
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpas_pasn_wd_sae_rx(struct wpa_supplicant *wpa_s, struct wpabuf *wd)
|
||||||
|
{
|
||||||
|
struct wpas_pasn *pasn = &wpa_s->pasn;
|
||||||
|
const u8 *data;
|
||||||
|
size_t buf_len;
|
||||||
|
u16 len, res, alg, seq, status;
|
||||||
|
int groups[] = { pasn->group, 0 };
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!wd)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
data = wpabuf_head_u8(wd);
|
||||||
|
buf_len = wpabuf_len(wd);
|
||||||
|
|
||||||
|
/* first handle the commit message */
|
||||||
|
if (buf_len < 2) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short (commit)");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = WPA_GET_LE16(data);
|
||||||
|
if (len < 6 || buf_len - 2 < len) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short for commit");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf_len -= 2;
|
||||||
|
data += 2;
|
||||||
|
|
||||||
|
alg = WPA_GET_LE16(data);
|
||||||
|
seq = WPA_GET_LE16(data + 2);
|
||||||
|
status = WPA_GET_LE16(data + 4);
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: SAE: commit: alg=%u, seq=%u, status=%u",
|
||||||
|
alg, seq, status);
|
||||||
|
|
||||||
|
/* TODO: SAE H2E */
|
||||||
|
if (alg != WLAN_AUTH_SAE || seq != 1 || status != WLAN_STATUS_SUCCESS) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: SAE: dropping peer commit");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = sae_parse_commit(&pasn->sae, data + 6, len - 6, NULL, 0, groups,
|
||||||
|
0);
|
||||||
|
if (res != WLAN_STATUS_SUCCESS) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: SAE failed parsing commit");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process the commit message and derive the PMK */
|
||||||
|
ret = sae_process_commit(&pasn->sae);
|
||||||
|
if (ret) {
|
||||||
|
wpa_printf(MSG_DEBUG, "SAE: Failed to process peer commit");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf_len -= len;
|
||||||
|
data += len;
|
||||||
|
|
||||||
|
/* Handle the confirm message */
|
||||||
|
if (buf_len < 2) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short (confirm)");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = WPA_GET_LE16(data);
|
||||||
|
if (len < 6 || buf_len - 2 < len) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short for confirm");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf_len -= 2;
|
||||||
|
data += 2;
|
||||||
|
|
||||||
|
alg = WPA_GET_LE16(data);
|
||||||
|
seq = WPA_GET_LE16(data + 2);
|
||||||
|
status = WPA_GET_LE16(data + 4);
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: SAE confirm: alg=%u, seq=%u, status=%u",
|
||||||
|
alg, seq, status);
|
||||||
|
|
||||||
|
if (alg != WLAN_AUTH_SAE || seq != 2 || status != WLAN_STATUS_SUCCESS) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: Dropping peer SAE confirm");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = sae_check_confirm(&pasn->sae, data + 6, len - 6);
|
||||||
|
if (res != WLAN_STATUS_SUCCESS) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: SAE failed checking confirm");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: SAE completed successfully");
|
||||||
|
pasn->sae.state = SAE_ACCEPTED;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct wpabuf * wpas_pasn_wd_sae_confirm(struct wpa_supplicant *wpa_s)
|
||||||
|
{
|
||||||
|
struct wpas_pasn *pasn = &wpa_s->pasn;
|
||||||
|
struct wpabuf *buf = NULL;
|
||||||
|
|
||||||
|
/* Need to add the entire authentication frame body */
|
||||||
|
buf = wpabuf_alloc(6 + SAE_CONFIRM_MAX_LEN);
|
||||||
|
if (!buf) {
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: Failed to allocate SAE buffer");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpabuf_put_le16(buf, WLAN_AUTH_SAE);
|
||||||
|
wpabuf_put_le16(buf, 2);
|
||||||
|
wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
|
||||||
|
|
||||||
|
sae_write_confirm(&pasn->sae, buf);
|
||||||
|
pasn->sae.state = SAE_CONFIRMED;
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_SAE */
|
||||||
|
|
||||||
|
|
||||||
|
static struct wpabuf * wpas_pasn_get_wrapped_data(struct wpa_supplicant *wpa_s)
|
||||||
|
{
|
||||||
|
struct wpas_pasn *pasn = &wpa_s->pasn;
|
||||||
|
|
||||||
|
if (pasn->using_pmksa)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
switch (pasn->akmp) {
|
switch (pasn->akmp) {
|
||||||
case WPA_KEY_MGMT_PASN:
|
case WPA_KEY_MGMT_PASN:
|
||||||
/* no wrapped data */
|
/* no wrapped data */
|
||||||
return NULL;
|
return NULL;
|
||||||
case WPA_KEY_MGMT_SAE:
|
case WPA_KEY_MGMT_SAE:
|
||||||
|
#ifdef CONFIG_SAE
|
||||||
|
if (pasn->trans_seq == 0)
|
||||||
|
return wpas_pasn_wd_sae_commit(wpa_s);
|
||||||
|
if (pasn->trans_seq == 2)
|
||||||
|
return wpas_pasn_wd_sae_confirm(wpa_s);
|
||||||
|
#endif /* CONFIG_SAE */
|
||||||
|
/* fall through */
|
||||||
case WPA_KEY_MGMT_FILS_SHA256:
|
case WPA_KEY_MGMT_FILS_SHA256:
|
||||||
case WPA_KEY_MGMT_FILS_SHA384:
|
case WPA_KEY_MGMT_FILS_SHA384:
|
||||||
case WPA_KEY_MGMT_FT_PSK:
|
case WPA_KEY_MGMT_FT_PSK:
|
||||||
|
@ -84,6 +276,9 @@ static struct wpabuf * wpas_pasn_get_wrapped_data(struct wpas_pasn *pasn)
|
||||||
|
|
||||||
static u8 wpas_pasn_get_wrapped_data_format(struct wpas_pasn *pasn)
|
static u8 wpas_pasn_get_wrapped_data_format(struct wpas_pasn *pasn)
|
||||||
{
|
{
|
||||||
|
if (pasn->using_pmksa)
|
||||||
|
return WPA_PASN_WRAPPED_DATA_NO;
|
||||||
|
|
||||||
/* Note: Valid AKMP is expected to already be validated */
|
/* Note: Valid AKMP is expected to already be validated */
|
||||||
switch (pasn->akmp) {
|
switch (pasn->akmp) {
|
||||||
case WPA_KEY_MGMT_SAE:
|
case WPA_KEY_MGMT_SAE:
|
||||||
|
@ -141,7 +336,7 @@ static struct wpabuf * wpas_pasn_build_auth_1(struct wpa_supplicant *wpa_s)
|
||||||
* Note: Even when PMKSA is available, also add wrapped data as
|
* Note: Even when PMKSA is available, also add wrapped data as
|
||||||
* it is possible that the PMKID is no longer valid at the AP.
|
* it is possible that the PMKID is no longer valid at the AP.
|
||||||
*/
|
*/
|
||||||
wrapped_data_buf = wpas_pasn_get_wrapped_data(pasn);
|
wrapped_data_buf = wpas_pasn_get_wrapped_data(wpa_s);
|
||||||
} else {
|
} else {
|
||||||
pmksa = NULL;
|
pmksa = NULL;
|
||||||
}
|
}
|
||||||
|
@ -210,7 +405,7 @@ static struct wpabuf * wpas_pasn_build_auth_3(struct wpa_supplicant *wpa_s)
|
||||||
wpa_s->own_addr, pasn->bssid,
|
wpa_s->own_addr, pasn->bssid,
|
||||||
pasn->trans_seq + 1, WLAN_STATUS_SUCCESS);
|
pasn->trans_seq + 1, WLAN_STATUS_SUCCESS);
|
||||||
|
|
||||||
wrapped_data_buf = wpas_pasn_get_wrapped_data(pasn);
|
wrapped_data_buf = wpas_pasn_get_wrapped_data(wpa_s);
|
||||||
|
|
||||||
if (!wrapped_data_buf)
|
if (!wrapped_data_buf)
|
||||||
wrapped_data = WPA_PASN_WRAPPED_DATA_NO;
|
wrapped_data = WPA_PASN_WRAPPED_DATA_NO;
|
||||||
|
@ -275,6 +470,7 @@ static void wpas_pasn_reset(struct wpa_supplicant *wpa_s)
|
||||||
pasn->group = 0;
|
pasn->group = 0;
|
||||||
pasn->trans_seq = 0;
|
pasn->trans_seq = 0;
|
||||||
pasn->pmk_len = 0;
|
pasn->pmk_len = 0;
|
||||||
|
pasn->using_pmksa = false;
|
||||||
|
|
||||||
forced_memzero(pasn->pmk, sizeof(pasn->pmk));
|
forced_memzero(pasn->pmk, sizeof(pasn->pmk));
|
||||||
forced_memzero(&pasn->ptk, sizeof(pasn->ptk));
|
forced_memzero(&pasn->ptk, sizeof(pasn->ptk));
|
||||||
|
@ -283,6 +479,9 @@ static void wpas_pasn_reset(struct wpa_supplicant *wpa_s)
|
||||||
wpabuf_free(pasn->beacon_rsne);
|
wpabuf_free(pasn->beacon_rsne);
|
||||||
pasn->beacon_rsne = NULL;
|
pasn->beacon_rsne = NULL;
|
||||||
|
|
||||||
|
#ifdef CONFIG_SAE
|
||||||
|
sae_clear_data(&pasn->sae);
|
||||||
|
#endif /* CONFIG_SAE */
|
||||||
pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,11 +517,35 @@ static int wpas_pasn_set_pmk(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
pasn->pmk_len = pmksa->pmk_len;
|
pasn->pmk_len = pmksa->pmk_len;
|
||||||
os_memcpy(pasn->pmk, pmksa->pmk, pmksa->pmk_len);
|
os_memcpy(pasn->pmk, pmksa->pmk, pmksa->pmk_len);
|
||||||
|
pasn->using_pmksa = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SAE
|
||||||
|
if (pasn->akmp == WPA_KEY_MGMT_SAE) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = wpas_pasn_wd_sae_rx(wpa_s, wrapped_data);
|
||||||
|
if (ret) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"PASN: Failed processing SAE wrapped data");
|
||||||
|
pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "PASN: Success deriving PMK with SAE");
|
||||||
|
pasn->pmk_len = PMK_LEN;
|
||||||
|
os_memcpy(pasn->pmk, pasn->sae.pmk, PMK_LEN);
|
||||||
|
|
||||||
|
wpa_pasn_pmksa_cache_add(wpa_s->wpa, pasn->pmk,
|
||||||
|
pasn->pmk_len, pasn->sae.pmkid,
|
||||||
|
pasn->bssid, pasn->akmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_SAE */
|
||||||
|
|
||||||
/* TODO: Derive PMK based on wrapped data */
|
/* TODO: Derive PMK based on wrapped data */
|
||||||
wpa_printf(MSG_DEBUG, "PASN: Missing implementation to derive PMK");
|
wpa_printf(MSG_DEBUG, "PASN: Missing implementation to derive PMK");
|
||||||
pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
@ -332,9 +555,11 @@ static int wpas_pasn_set_pmk(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
static int wpas_pasn_start(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
static int wpas_pasn_start(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||||
int akmp, int cipher, u16 group, int freq,
|
int akmp, int cipher, u16 group, int freq,
|
||||||
const u8 *beacon_rsne, u8 beacon_rsne_len)
|
const u8 *beacon_rsne, u8 beacon_rsne_len,
|
||||||
|
int network_id)
|
||||||
{
|
{
|
||||||
struct wpas_pasn *pasn = &wpa_s->pasn;
|
struct wpas_pasn *pasn = &wpa_s->pasn;
|
||||||
|
struct wpa_ssid *ssid = NULL;
|
||||||
struct wpabuf *frame;
|
struct wpabuf *frame;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -345,11 +570,21 @@ static int wpas_pasn_start(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssid = wpa_config_get_network(wpa_s->conf, network_id);
|
||||||
|
|
||||||
switch (akmp) {
|
switch (akmp) {
|
||||||
case WPA_KEY_MGMT_PASN:
|
case WPA_KEY_MGMT_PASN:
|
||||||
break;
|
break;
|
||||||
#ifdef CONFIG_SAE
|
#ifdef CONFIG_SAE
|
||||||
case WPA_KEY_MGMT_SAE:
|
case WPA_KEY_MGMT_SAE:
|
||||||
|
if (!ssid) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"PASN: No network profile found for SAE");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
pasn->sae.state = SAE_NOTHING;
|
||||||
|
pasn->sae.send_confirm = 0;
|
||||||
|
pasn->ssid = ssid;
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_SAE */
|
#endif /* CONFIG_SAE */
|
||||||
#ifdef CONFIG_FILS
|
#ifdef CONFIG_FILS
|
||||||
|
@ -497,7 +732,8 @@ static void wpas_pasn_auth_start_cb(struct wpa_radio_work *work, int deinit)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = wpas_pasn_start(wpa_s, awork->bssid, awork->akmp, awork->cipher,
|
ret = wpas_pasn_start(wpa_s, awork->bssid, awork->akmp, awork->cipher,
|
||||||
awork->group, bss->freq, rsne, *(rsne + 1) + 2);
|
awork->group, bss->freq, rsne, *(rsne + 1) + 2,
|
||||||
|
awork->network_id);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"PASN: Failed to start PASN authentication");
|
"PASN: Failed to start PASN authentication");
|
||||||
|
@ -514,7 +750,7 @@ fail:
|
||||||
|
|
||||||
|
|
||||||
int wpas_pasn_auth_start(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
int wpas_pasn_auth_start(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||||
int akmp, int cipher, u16 group)
|
int akmp, int cipher, u16 group, int network_id)
|
||||||
{
|
{
|
||||||
struct wpa_pasn_auth_work *awork;
|
struct wpa_pasn_auth_work *awork;
|
||||||
struct wpa_bss *bss;
|
struct wpa_bss *bss;
|
||||||
|
@ -558,6 +794,7 @@ int wpas_pasn_auth_start(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||||
awork->akmp = akmp;
|
awork->akmp = akmp;
|
||||||
awork->cipher = cipher;
|
awork->cipher = cipher;
|
||||||
awork->group = group;
|
awork->group = group;
|
||||||
|
awork->network_id = network_id;
|
||||||
|
|
||||||
if (radio_add_work(wpa_s, bss->freq, "pasn-start-auth", 1,
|
if (radio_add_work(wpa_s, bss->freq, "pasn-start-auth", 1,
|
||||||
wpas_pasn_auth_start_cb, awork) < 0) {
|
wpas_pasn_auth_start_cb, awork) < 0) {
|
||||||
|
|
|
@ -3877,7 +3877,7 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
|
||||||
#ifdef CONFIG_PASN
|
#ifdef CONFIG_PASN
|
||||||
{ "pasn_auth_start", wpa_cli_cmd_pasn_auth_start, NULL,
|
{ "pasn_auth_start", wpa_cli_cmd_pasn_auth_start, NULL,
|
||||||
cli_cmd_flag_none,
|
cli_cmd_flag_none,
|
||||||
"bssid=<BSSID> akmp=<WPA key mgmt> cipher=<WPA cipher> group=<group> = Start PASN authentication" },
|
"bssid=<BSSID> akmp=<WPA key mgmt> cipher=<WPA cipher> group=<group> nid=<network id> = Start PASN authentication" },
|
||||||
{ "pasn_auth_stop", wpa_cli_cmd_pasn_auth_stop, NULL,
|
{ "pasn_auth_stop", wpa_cli_cmd_pasn_auth_stop, NULL,
|
||||||
cli_cmd_flag_none,
|
cli_cmd_flag_none,
|
||||||
"= Stop PASN authentication" },
|
"= Stop PASN authentication" },
|
||||||
|
|
|
@ -528,12 +528,19 @@ struct wpas_pasn {
|
||||||
u8 bssid[ETH_ALEN];
|
u8 bssid[ETH_ALEN];
|
||||||
size_t pmk_len;
|
size_t pmk_len;
|
||||||
u8 pmk[PMK_LEN_MAX];
|
u8 pmk[PMK_LEN_MAX];
|
||||||
|
bool using_pmksa;
|
||||||
|
|
||||||
u8 hash[SHA384_MAC_LEN];
|
u8 hash[SHA384_MAC_LEN];
|
||||||
|
|
||||||
struct wpabuf *beacon_rsne;
|
struct wpabuf *beacon_rsne;
|
||||||
struct wpa_ptk ptk;
|
struct wpa_ptk ptk;
|
||||||
struct crypto_ecdh *ecdh;
|
struct crypto_ecdh *ecdh;
|
||||||
|
|
||||||
|
#ifdef CONFIG_SAE
|
||||||
|
struct sae_data sae;
|
||||||
|
#endif /* CONFIG_SAE */
|
||||||
|
|
||||||
|
const struct wpa_ssid *ssid;
|
||||||
};
|
};
|
||||||
#endif /* CONFIG_PASN */
|
#endif /* CONFIG_PASN */
|
||||||
|
|
||||||
|
@ -1685,7 +1692,7 @@ void wpas_handle_assoc_resp_mscs(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||||
|
|
||||||
int wpas_pasn_auth_start(struct wpa_supplicant *wpa_s,
|
int wpas_pasn_auth_start(struct wpa_supplicant *wpa_s,
|
||||||
const u8 *bssid, int akmp, int cipher,
|
const u8 *bssid, int akmp, int cipher,
|
||||||
u16 group);
|
u16 group, int network_id);
|
||||||
void wpas_pasn_auth_stop(struct wpa_supplicant *wpa_s);
|
void wpas_pasn_auth_stop(struct wpa_supplicant *wpa_s);
|
||||||
int wpas_pasn_auth_tx_status(struct wpa_supplicant *wpa_s,
|
int wpas_pasn_auth_tx_status(struct wpa_supplicant *wpa_s,
|
||||||
const u8 *data, size_t data_len, u8 acked);
|
const u8 *data, size_t data_len, u8 acked);
|
||||||
|
|
Loading…
Add table
Reference in a new issue