aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2019-04-19 20:05:50 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2019-04-19 20:05:50 +0000
commit200b74922ba9c9147812b97b8d1defe9b92049ba (patch)
tree4cbaa9a808a257f8ae3a10113a7f25c96e8a5ab9
parent33df1fd2f293bdf6a26938c701064f94d620c92a (diff)
parent5f92bc919aede94d14fc7eae550de2a236127c19 (diff)
downloadwpa_supplicant_8-200b74922ba9c9147812b97b8d1defe9b92049ba.tar.gz
Merge "[wpa_supplicant] Cumulative patch from 6151c9b90" into qt-dev
-rw-r--r--hostapd/ctrl_iface.c2
-rw-r--r--src/ap/ap_drv_ops.h10
-rw-r--r--src/ap/hostapd.c1
-rw-r--r--src/ap/ieee802_11.c40
-rw-r--r--src/crypto/crypto.h8
-rw-r--r--src/crypto/crypto_internal.c3
-rw-r--r--src/crypto/crypto_libtomcrypt.c3
-rw-r--r--src/crypto/crypto_linux.c3
-rw-r--r--src/crypto/crypto_openssl.c12
-rw-r--r--src/crypto/crypto_wolfssl.c14
-rw-r--r--src/crypto/tls_openssl.c3
-rw-r--r--src/drivers/driver.h6
-rw-r--r--src/drivers/driver_bsd.c2
-rw-r--r--src/drivers/driver_nl80211.c40
-rw-r--r--src/drivers/driver_nl80211_event.c31
-rw-r--r--src/eap_common/eap_pwd_common.c66
-rw-r--r--src/eap_peer/eap_mschapv2.c10
-rw-r--r--src/eap_peer/eap_pwd.c32
-rw-r--r--src/eap_server/eap_server_mschapv2.c10
-rw-r--r--src/eap_server/eap_server_pwd.c47
-rw-r--r--src/pae/ieee802_1x_cp.c4
-rw-r--r--src/rsn_supp/wpa.c37
-rw-r--r--wpa_supplicant/ctrl_iface.c2
-rw-r--r--wpa_supplicant/events.c22
-rw-r--r--wpa_supplicant/mesh_mpm.c2
-rw-r--r--wpa_supplicant/p2p_supplicant.c14
-rw-r--r--wpa_supplicant/rrm.c36
-rw-r--r--wpa_supplicant/sme.c18
-rw-r--r--wpa_supplicant/wpa_supplicant.c19
-rw-r--r--wpa_supplicant/wpa_supplicant.conf9
30 files changed, 289 insertions, 217 deletions
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index 78e52a6f..e4b16e61 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -883,7 +883,7 @@ static int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
/* TODO: TSF configurable/learnable */
bss_term_dur[0] = 4; /* Subelement ID */
bss_term_dur[1] = 10; /* Length */
- os_memset(bss_term_dur, 2, 8);
+ os_memset(&bss_term_dur[2], 0, 8);
end = os_strchr(pos, ',');
if (end == NULL) {
wpa_printf(MSG_DEBUG, "Invalid bss_term data");
diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
index d45ab846..de40171e 100644
--- a/src/ap/ap_drv_ops.h
+++ b/src/ap/ap_drv_ops.h
@@ -364,4 +364,14 @@ static inline int hostapd_drv_channel_info(struct hostapd_data *hapd,
return hapd->driver->channel_info(hapd->drv_priv, ci);
}
+static inline int
+hostapd_drv_send_external_auth_status(struct hostapd_data *hapd,
+ struct external_auth *params)
+{
+ if (!hapd->driver || !hapd->drv_priv ||
+ !hapd->driver->send_external_auth_status)
+ return -1;
+ return hapd->driver->send_external_auth_status(hapd->drv_priv, params);
+}
+
#endif /* AP_DRV_OPS */
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 77742f44..20c8e8f5 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -352,6 +352,7 @@ static void hostapd_free_hapd_data(struct hostapd_data *hapd)
return;
}
hapd->started = 0;
+ hapd->beacon_set_done = 0;
wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface);
iapp_deinit(hapd->iapp);
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 28aca466..5cd25626 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -701,6 +701,21 @@ static void sae_set_retransmit_timer(struct hostapd_data *hapd,
}
+static void sae_sme_send_external_auth_status(struct hostapd_data *hapd,
+ struct sta_info *sta, u16 status)
+{
+ struct external_auth params;
+
+ os_memset(&params, 0, sizeof(params));
+ params.status = status;
+ params.bssid = sta->addr;
+ if (status == WLAN_STATUS_SUCCESS && sta->sae)
+ params.pmkid = sta->sae->pmkid;
+
+ hostapd_drv_send_external_auth_status(hapd, &params);
+}
+
+
void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta)
{
#ifndef CONFIG_NO_VLAN
@@ -739,14 +754,18 @@ void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta)
sae_set_state(sta, SAE_ACCEPTED, "Accept Confirm");
wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr,
sta->sae->pmk, sta->sae->pmkid);
+ sae_sme_send_external_auth_status(hapd, sta, WLAN_STATUS_SUCCESS);
}
static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
- const u8 *bssid, u8 auth_transaction, int allow_reuse)
+ const u8 *bssid, u8 auth_transaction, int allow_reuse,
+ int *sta_removed)
{
int ret;
+ *sta_removed = 0;
+
if (auth_transaction != 1 && auth_transaction != 2)
return WLAN_STATUS_UNSPECIFIED_FAILURE;
@@ -847,7 +866,7 @@ static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
* additional events.
*/
return sae_sm_step(hapd, sta, bssid, auth_transaction,
- 0);
+ 0, sta_removed);
}
break;
case SAE_CONFIRMED:
@@ -880,8 +899,9 @@ static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
wpa_printf(MSG_DEBUG, "SAE: remove the STA (" MACSTR
") doing reauthentication",
MAC2STR(sta->addr));
- ap_free_sta(hapd, sta);
wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
+ ap_free_sta(hapd, sta);
+ *sta_removed = 1;
} else if (auth_transaction == 1) {
wpa_printf(MSG_DEBUG, "SAE: Start reauthentication");
ret = auth_sae_send_commit(hapd, sta, bssid, 1);
@@ -963,6 +983,7 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
int *groups = hapd->conf->sae_groups;
int default_groups[] = { 19, 0 };
const u8 *pos, *end;
+ int sta_removed = 0;
if (!groups)
groups = default_groups;
@@ -1157,7 +1178,7 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
}
resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction,
- allow_reuse);
+ allow_reuse, &sta_removed);
} else if (auth_transaction == 2) {
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_DEBUG,
@@ -1198,7 +1219,8 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
}
sta->sae->rc = peer_send_confirm;
}
- resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction, 0);
+ resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction, 0,
+ &sta_removed);
} else {
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_DEBUG,
@@ -1210,7 +1232,7 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
}
reply:
- if (resp != WLAN_STATUS_SUCCESS) {
+ if (!sta_removed && resp != WLAN_STATUS_SUCCESS) {
pos = mgmt->u.auth.variable;
end = ((const u8 *) mgmt) + len;
@@ -1220,6 +1242,7 @@ reply:
!data && end - pos >= 2)
data = wpabuf_alloc_copy(pos, 2);
+ sae_sme_send_external_auth_status(hapd, sta, resp);
send_auth_reply(hapd, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
auth_transaction, resp,
data ? wpabuf_head(data) : (u8 *) "",
@@ -1227,8 +1250,9 @@ reply:
}
remove_sta:
- if (sta->added_unassoc && (resp != WLAN_STATUS_SUCCESS ||
- status_code != WLAN_STATUS_SUCCESS)) {
+ if (!sta_removed && sta->added_unassoc &&
+ (resp != WLAN_STATUS_SUCCESS ||
+ status_code != WLAN_STATUS_SUCCESS)) {
hostapd_drv_sta_remove(hapd, sta->addr);
sta->added_unassoc = 0;
}
diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h
index a28ddbd7..12109ce8 100644
--- a/src/crypto/crypto.h
+++ b/src/crypto/crypto.h
@@ -704,14 +704,6 @@ struct crypto_ec * crypto_ec_init(int group);
void crypto_ec_deinit(struct crypto_ec *e);
/**
- * crypto_ec_cofactor - Set the cofactor into the big number
- * @e: EC context from crypto_ec_init()
- * @cofactor: Cofactor of curve.
- * Returns: 0 on success, -1 on failure
- */
-int crypto_ec_cofactor(struct crypto_ec *e, struct crypto_bignum *cofactor);
-
-/**
* crypto_ec_prime_len - Get length of the prime in octets
* @e: EC context from crypto_ec_init()
* Returns: Length of the prime defining the group
diff --git a/src/crypto/crypto_internal.c b/src/crypto/crypto_internal.c
index d391f48a..aad40af1 100644
--- a/src/crypto/crypto_internal.c
+++ b/src/crypto/crypto_internal.c
@@ -310,6 +310,9 @@ int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
os_free(ctx);
+ if (TEST_FAIL())
+ return -1;
+
return 0;
}
diff --git a/src/crypto/crypto_libtomcrypt.c b/src/crypto/crypto_libtomcrypt.c
index 980fa422..ed30efa0 100644
--- a/src/crypto/crypto_libtomcrypt.c
+++ b/src/crypto/crypto_libtomcrypt.c
@@ -278,6 +278,9 @@ int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
os_free(ctx);
+ if (TEST_FAIL())
+ return -1;
+
return ret;
}
diff --git a/src/crypto/crypto_linux.c b/src/crypto/crypto_linux.c
index 8099193b..17244561 100644
--- a/src/crypto/crypto_linux.c
+++ b/src/crypto/crypto_linux.c
@@ -386,6 +386,9 @@ int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
}
crypto_hash_deinit(ctx);
+
+ if (TEST_FAIL())
+ return -1;
return 0;
}
diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c
index 0f52101e..1b0c1ec9 100644
--- a/src/crypto/crypto_openssl.c
+++ b/src/crypto/crypto_openssl.c
@@ -1054,6 +1054,9 @@ int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
HMAC_CTX_free(ctx->ctx);
bin_clear_free(ctx, sizeof(*ctx));
+ if (TEST_FAIL())
+ return -1;
+
if (res == 1) {
*len = mdlen;
return 0;
@@ -1317,6 +1320,8 @@ int crypto_bignum_to_bin(const struct crypto_bignum *a,
int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m)
{
+ if (TEST_FAIL())
+ return -1;
return BN_rand_range((BIGNUM *) r, (const BIGNUM *) m) == 1 ? 0 : -1;
}
@@ -1631,13 +1636,6 @@ void crypto_ec_deinit(struct crypto_ec *e)
}
-int crypto_ec_cofactor(struct crypto_ec *e, struct crypto_bignum *cofactor)
-{
- return EC_GROUP_get_cofactor(e->group, (BIGNUM *) cofactor,
- e->bnctx) == 0 ? -1 : 0;
-}
-
-
struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e)
{
if (TEST_FAIL())
diff --git a/src/crypto/crypto_wolfssl.c b/src/crypto/crypto_wolfssl.c
index 10cdae60..976a0086 100644
--- a/src/crypto/crypto_wolfssl.c
+++ b/src/crypto/crypto_wolfssl.c
@@ -953,6 +953,8 @@ int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
ret = 0;
done:
bin_clear_free(ctx, sizeof(*ctx));
+ if (TEST_FAIL())
+ return -1;
return ret;
}
@@ -1083,6 +1085,8 @@ int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m)
int ret = 0;
WC_RNG rng;
+ if (TEST_FAIL())
+ return -1;
if (wc_InitRng(&rng) != 0)
return -1;
if (mp_rand_prime((mp_int *) r,
@@ -1348,16 +1352,6 @@ void crypto_ec_deinit(struct crypto_ec* e)
}
-int crypto_ec_cofactor(struct crypto_ec *e, struct crypto_bignum *cofactor)
-{
- if (!e || !cofactor)
- return -1;
-
- mp_set((mp_int *) cofactor, e->key.dp->cofactor);
- return 0;
-}
-
-
struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e)
{
if (TEST_FAIL())
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index 7fde21cc..620254af 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -5055,6 +5055,9 @@ int tls_global_set_params(void *tls_ctx,
return -1;
#else /* OPENSSL_IS_BORINGSSL || < 1.0.2 */
#ifndef OPENSSL_NO_EC
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ SSL_CTX_set_ecdh_auto(ssl_ctx, 1);
+#endif
if (SSL_CTX_set1_curves_list(ssl_ctx,
params->openssl_ecdh_curves) !=
1) {
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 23423d92..e7c8f318 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -2156,17 +2156,19 @@ enum wpa_drv_update_connect_params_mask {
* use %WLAN_STATUS_UNSPECIFIED_FAILURE if wpa_supplicant cannot give
* the real status code for failures. Used only for the request interface
* from user space to the driver.
+ * @pmkid: Generated PMKID as part of external auth exchange (e.g., SAE).
*/
struct external_auth {
enum {
EXT_AUTH_START,
EXT_AUTH_ABORT,
} action;
- u8 bssid[ETH_ALEN];
- u8 ssid[SSID_MAX_LEN];
+ const u8 *bssid;
+ const u8 *ssid;
size_t ssid_len;
unsigned int key_mgmt_suite;
u16 status;
+ const u8 *pmkid;
};
/**
diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c
index 8621aa0b..46754968 100644
--- a/src/drivers/driver_bsd.c
+++ b/src/drivers/driver_bsd.c
@@ -143,7 +143,7 @@ bsd_get80211(void *priv, struct ieee80211req *ireq, int op, void *arg,
ireq->i_data = arg;
if (ioctl(drv->global->sock, SIOCG80211, ireq) < 0) {
- wpa_printf(MSG_ERROR, "ioctl[SIOCS80211, op=%u, "
+ wpa_printf(MSG_ERROR, "ioctl[SIOCG80211, op=%u, "
"arg_len=%u]: %s", op, arg_len, strerror(errno));
return -1;
}
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 661e34e6..21d1398e 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -307,6 +307,7 @@ void nl80211_mark_disconnected(struct wpa_driver_nl80211_data *drv)
os_memcpy(drv->prev_bssid, drv->bssid, ETH_ALEN);
drv->associated = 0;
os_memset(drv->bssid, 0, ETH_ALEN);
+ drv->first_bss->freq = 0;
}
@@ -2469,6 +2470,16 @@ static int nl80211_mgmt_subscribe_ap_dev_sme(struct i802_bss *bss)
if (nl80211_action_subscribe_ap(bss))
goto out_err;
+ if (bss->drv->device_ap_sme) {
+ u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_AUTH << 4);
+
+ /* Register for all Authentication frames */
+ if (nl80211_register_frame(bss, bss->nl_mgmt, type, NULL, 0)
+ < 0)
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Failed to subscribe to handle Authentication frames - SAE offload may not work");
+ }
+
nl80211_mgmt_handle_register_eloop(bss);
return 0;
@@ -4160,6 +4171,9 @@ static int wpa_driver_nl80211_set_ap(void *priv,
nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)))
goto fail;
+ if (drv->device_ap_sme && (params->key_mgmt_suites & WPA_KEY_MGMT_SAE))
+ nla_put_flag(msg, NL80211_ATTR_EXTERNAL_AUTH_SUPPORT);
+
wpa_printf(MSG_DEBUG, "nl80211: pairwise_ciphers=0x%x",
params->pairwise_ciphers);
num_suites = wpa_cipher_to_cipher_suites(params->pairwise_ciphers,
@@ -8272,6 +8286,7 @@ static void nl80211_poll_client(void *priv, const u8 *own_addr, const u8 *addr,
struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv;
struct nl_msg *msg;
+ u64 cookie;
int ret;
if (!drv->poll_command_supported) {
@@ -8285,11 +8300,16 @@ static void nl80211_poll_client(void *priv, const u8 *own_addr, const u8 *addr,
return;
}
- ret = send_and_recv_msgs(drv, msg, NULL, NULL);
+ ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
if (ret < 0) {
wpa_printf(MSG_DEBUG, "nl80211: Client probe request for "
MACSTR " failed: ret=%d (%s)",
MAC2STR(addr), ret, strerror(-ret));
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Client probe request addr=" MACSTR
+ " cookie=%llu", MAC2STR(addr),
+ (long long unsigned int) cookie);
}
}
@@ -10792,15 +10812,27 @@ static int nl80211_send_external_auth_status(void *priv,
struct nl_msg *msg = NULL;
int ret = -1;
+ /* External auth command/status is intended for drivers that implement
+ * intenral SME but want to offload authentication processing (e.g.,
+ * SAE) to hostapd/wpa_supplicant. Do nott send the status to drivers
+ * which do not support AP SME or use wpa_supplicant/hostapd SME.
+ */
+ if (!bss->drv->device_ap_sme ||
+ (drv->capa.flags & WPA_DRIVER_FLAGS_SME))
+ return -1;
+
wpa_dbg(drv->ctx, MSG_DEBUG,
"nl80211: External auth status: %u", params->status);
msg = nl80211_drv_msg(drv, 0, NL80211_CMD_EXTERNAL_AUTH);
if (!msg ||
nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, params->status) ||
- nla_put(msg, NL80211_ATTR_SSID, params->ssid_len,
- params->ssid) ||
- nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid))
+ (params->ssid && params->ssid_len &&
+ nla_put(msg, NL80211_ATTR_SSID, params->ssid_len, params->ssid)) ||
+ (params->pmkid &&
+ nla_put(msg, NL80211_ATTR_PMKID, PMKID_LEN, params->pmkid)) ||
+ (params->bssid &&
+ nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid)))
goto fail;
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
msg = NULL;
diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
index ffddd94d..ee7b4da3 100644
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -267,8 +267,6 @@ static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
event.assoc_info.req_ies_len = nla_len(req_ie);
}
- event.assoc_info.freq = drv->assoc_freq;
-
/* When this association was initiated outside of wpa_supplicant,
* drv->ssid needs to be set here to satisfy later checking. */
ssid_len = nl80211_get_assoc_ssid(drv, drv->ssid);
@@ -279,6 +277,9 @@ static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
wpa_ssid_txt(drv->ssid, drv->ssid_len));
}
+ event.assoc_info.freq = drv->assoc_freq;
+ drv->first_bss->freq = drv->assoc_freq;
+
nl80211_parse_wmm_params(wmm, &event.assoc_info.wmm_params);
wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
@@ -408,6 +409,7 @@ static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
}
event.assoc_info.freq = nl80211_get_assoc_freq(drv);
+ drv->first_bss->freq = drv->assoc_freq;
if ((!ssid || ssid[1] == 0 || ssid[1] > 32) &&
(ssid_len = nl80211_get_assoc_ssid(drv, drv->ssid)) > 0) {
@@ -1436,16 +1438,23 @@ static void nl80211_client_probe_event(struct wpa_driver_nl80211_data *drv,
struct nlattr **tb)
{
union wpa_event_data data;
+ const u8 *addr;
+ u64 cookie = 0;
- wpa_printf(MSG_DEBUG, "nl80211: Probe client event");
-
- if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_ACK])
+ addr = nla_data(tb[NL80211_ATTR_MAC]);
+ if (!addr)
+ return;
+ if (tb[NL80211_ATTR_COOKIE])
+ cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
+ wpa_printf(MSG_DEBUG, "nl80211: Probe client event (addr=" MACSTR
+ " ack=%d cookie=%llu)", MAC2STR(addr),
+ tb[NL80211_ATTR_ACK] != NULL,
+ (long long unsigned int) cookie);
+ if (!tb[NL80211_ATTR_ACK])
return;
os_memset(&data, 0, sizeof(data));
- os_memcpy(data.client_poll.addr,
- nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
-
+ os_memcpy(data.client_poll.addr, addr, ETH_ALEN);
wpa_supplicant_event(drv->ctx, EVENT_DRIVER_CLIENT_POLL_OK, &data);
}
@@ -2269,11 +2278,9 @@ static void nl80211_external_auth(struct wpa_driver_nl80211_data *drv,
event.external_auth.ssid_len = nla_len(tb[NL80211_ATTR_SSID]);
if (event.external_auth.ssid_len > SSID_MAX_LEN)
return;
- os_memcpy(event.external_auth.ssid, nla_data(tb[NL80211_ATTR_SSID]),
- event.external_auth.ssid_len);
+ event.external_auth.ssid = nla_data(tb[NL80211_ATTR_SSID]);
- os_memcpy(event.external_auth.bssid, nla_data(tb[NL80211_ATTR_BSSID]),
- ETH_ALEN);
+ event.external_auth.bssid = nla_data(tb[NL80211_ATTR_BSSID]);
wpa_printf(MSG_DEBUG,
"nl80211: External auth action: %u, AKM: 0x%x",
diff --git a/src/eap_common/eap_pwd_common.c b/src/eap_common/eap_pwd_common.c
index 4288b529..884150e6 100644
--- a/src/eap_common/eap_pwd_common.c
+++ b/src/eap_common/eap_pwd_common.c
@@ -85,10 +85,23 @@ static int eap_pwd_kdf(const u8 *key, size_t keylen, const u8 *label,
}
+static int eap_pwd_suitable_group(u16 num)
+{
+ /* Do not allow ECC groups with prime under 256 bits based on guidance
+ * for the similar design in SAE. */
+ return num == 19 || num == 20 || num == 21 ||
+ num == 28 || num == 29 || num == 30;
+}
+
+
EAP_PWD_group * get_eap_pwd_group(u16 num)
{
EAP_PWD_group *grp;
+ if (!eap_pwd_suitable_group(num)) {
+ wpa_printf(MSG_INFO, "EAP-pwd: unsuitable group %u", num);
+ return NULL;
+ }
grp = os_zalloc(sizeof(EAP_PWD_group));
if (!grp)
return NULL;
@@ -138,7 +151,7 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
* mask */
size_t primebytelen = 0, primebitlen;
- struct crypto_bignum *x_candidate = NULL, *cofactor = NULL;
+ struct crypto_bignum *x_candidate = NULL;
const struct crypto_bignum *prime;
u8 mask, found_ctr = 0, is_odd = 0;
@@ -148,21 +161,15 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
os_memset(x_bin, 0, sizeof(x_bin));
prime = crypto_ec_get_prime(grp->group);
- cofactor = crypto_bignum_init();
grp->pwe = crypto_ec_point_init(grp->group);
tmp1 = crypto_bignum_init();
pm1 = crypto_bignum_init();
one = crypto_bignum_init_set((const u8 *) "\x01", 1);
- if (!cofactor || !grp->pwe || !tmp1 || !pm1 || !one) {
+ if (!grp->pwe || !tmp1 || !pm1 || !one) {
wpa_printf(MSG_INFO, "EAP-pwd: unable to create bignums");
goto fail;
}
- if (crypto_ec_cofactor(grp->group, cofactor) < 0) {
- wpa_printf(MSG_INFO, "EAP-pwd: unable to get cofactor for "
- "curve");
- goto fail;
- }
primebitlen = crypto_ec_prime_len_bits(grp->group);
primebytelen = crypto_ec_prime_len(grp->group);
if ((prfbuf = os_malloc(primebytelen)) == NULL) {
@@ -327,19 +334,6 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
goto fail;
}
- if (!crypto_bignum_is_one(cofactor)) {
- /* make sure the point is not in a small sub-group */
- if (crypto_ec_point_mul(grp->group, grp->pwe, cofactor,
- grp->pwe) != 0) {
- wpa_printf(MSG_INFO,
- "EAP-pwd: cannot multiply generator by order");
- goto fail;
- }
- if (crypto_ec_point_is_at_infinity(grp->group, grp->pwe)) {
- wpa_printf(MSG_INFO, "EAP-pwd: point is at infinity");
- goto fail;
- }
- }
wpa_printf(MSG_DEBUG, "EAP-pwd: found a PWE in %02d tries", found_ctr);
if (0) {
@@ -349,7 +343,6 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
ret = 1;
}
/* cleanliness and order.... */
- crypto_bignum_deinit(cofactor, 1);
crypto_bignum_deinit(x_candidate, 1);
crypto_bignum_deinit(pm1, 0);
crypto_bignum_deinit(tmp1, 1);
@@ -451,7 +444,6 @@ struct crypto_ec_point * eap_pwd_get_element(EAP_PWD_group *group,
struct crypto_ec_point *element;
const struct crypto_bignum *prime;
size_t prime_len;
- struct crypto_bignum *cofactor = NULL;
prime = crypto_ec_get_prime(group->group);
prime_len = crypto_ec_prime_len(group->group);
@@ -476,35 +468,7 @@ struct crypto_ec_point * eap_pwd_get_element(EAP_PWD_group *group,
goto fail;
}
- cofactor = crypto_bignum_init();
- if (!cofactor || crypto_ec_cofactor(group->group, cofactor) < 0) {
- wpa_printf(MSG_INFO,
- "EAP-pwd: Unable to get cofactor for curve");
- goto fail;
- }
-
- if (!crypto_bignum_is_one(cofactor)) {
- struct crypto_ec_point *point;
- int ok = 1;
-
- /* check to ensure peer's element is not in a small sub-group */
- point = crypto_ec_point_init(group->group);
- if (!point ||
- crypto_ec_point_mul(group->group, element,
- cofactor, point) != 0 ||
- crypto_ec_point_is_at_infinity(group->group, point))
- ok = 0;
- crypto_ec_point_deinit(point, 0);
-
- if (!ok) {
- wpa_printf(MSG_INFO,
- "EAP-pwd: Small sub-group check on peer element failed");
- goto fail;
- }
- }
-
out:
- crypto_bignum_deinit(cofactor, 0);
return element;
fail:
crypto_ec_point_deinit(element, 0);
diff --git a/src/eap_peer/eap_mschapv2.c b/src/eap_peer/eap_mschapv2.c
index 877495cf..249baec8 100644
--- a/src/eap_peer/eap_mschapv2.c
+++ b/src/eap_peer/eap_mschapv2.c
@@ -856,9 +856,13 @@ static u8 * eap_mschapv2_getKey(struct eap_sm *sm, void *priv, size_t *len)
/* MSK = server MS-MPPE-Recv-Key | MS-MPPE-Send-Key, i.e.,
* peer MS-MPPE-Send-Key | MS-MPPE-Recv-Key */
- get_asymetric_start_key(data->master_key, key, MSCHAPV2_KEY_LEN, 1, 0);
- get_asymetric_start_key(data->master_key, key + MSCHAPV2_KEY_LEN,
- MSCHAPV2_KEY_LEN, 0, 0);
+ if (get_asymetric_start_key(data->master_key, key, MSCHAPV2_KEY_LEN, 1,
+ 0) < 0 ||
+ get_asymetric_start_key(data->master_key, key + MSCHAPV2_KEY_LEN,
+ MSCHAPV2_KEY_LEN, 0, 0) < 0) {
+ os_free(key);
+ return NULL;
+ }
wpa_hexdump_key(MSG_DEBUG, "EAP-MSCHAPV2: Derived key",
key, key_len);
diff --git a/src/eap_peer/eap_pwd.c b/src/eap_peer/eap_pwd.c
index 4be4fcf3..76fcad4a 100644
--- a/src/eap_peer/eap_pwd.c
+++ b/src/eap_peer/eap_pwd.c
@@ -309,7 +309,7 @@ eap_pwd_perform_commit_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
const u8 *payload, size_t payload_len)
{
struct crypto_ec_point *K = NULL;
- struct crypto_bignum *mask = NULL, *cofactor = NULL;
+ struct crypto_bignum *mask = NULL;
const u8 *ptr = payload;
u8 *scalar, *element;
size_t prime_len, order_len;
@@ -527,21 +527,14 @@ eap_pwd_perform_commit_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
data->private_value = crypto_bignum_init();
data->my_element = crypto_ec_point_init(data->grp->group);
- cofactor = crypto_bignum_init();
data->my_scalar = crypto_bignum_init();
mask = crypto_bignum_init();
- if (!data->private_value || !data->my_element || !cofactor ||
+ if (!data->private_value || !data->my_element ||
!data->my_scalar || !mask) {
wpa_printf(MSG_INFO, "EAP-PWD (peer): scalar allocation fail");
goto fin;
}
- if (crypto_ec_cofactor(data->grp->group, cofactor) < 0) {
- wpa_printf(MSG_INFO, "EAP-pwd (peer): unable to get cofactor "
- "for curve");
- goto fin;
- }
-
if (eap_pwd_get_rand_mask(data->grp, data->private_value, mask,
data->my_scalar) < 0)
goto fin;
@@ -595,17 +588,8 @@ eap_pwd_perform_commit_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
goto fin;
}
- /* ensure that the shared key isn't in a small sub-group */
- if (!crypto_bignum_is_one(cofactor)) {
- if (crypto_ec_point_mul(data->grp->group, K, cofactor, K) < 0) {
- wpa_printf(MSG_INFO, "EAP-PWD (peer): cannot multiply "
- "shared key point by order");
- goto fin;
- }
- }
-
/*
- * This check is strictly speaking just for the case above where
+ * This check is strictly speaking just for the case where
* co-factor > 1 but it was suggested that even though this is probably
* never going to happen it is a simple and safe check "just to be
* sure" so let's be safe.
@@ -644,7 +628,6 @@ eap_pwd_perform_commit_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
fin:
crypto_bignum_deinit(mask, 1);
- crypto_bignum_deinit(cofactor, 1);
crypto_ec_point_deinit(K, 1);
if (data->outbuf == NULL)
eap_pwd_state(data, FAILURE);
@@ -949,6 +932,13 @@ eap_pwd_process(struct eap_sm *sm, void *priv, struct eap_method_ret *ret,
* buffer and ACK the fragment
*/
if (EAP_PWD_GET_MORE_BIT(lm_exch) || data->in_frag_pos) {
+ if (!data->inbuf) {
+ wpa_printf(MSG_DEBUG,
+ "EAP-pwd: No buffer for reassembly");
+ ret->methodState = METHOD_DONE;
+ ret->decision = DECISION_FAIL;
+ return NULL;
+ }
data->in_frag_pos += len;
if (data->in_frag_pos > wpabuf_size(data->inbuf)) {
wpa_printf(MSG_INFO, "EAP-pwd: Buffer overflow attack "
@@ -975,7 +965,7 @@ eap_pwd_process(struct eap_sm *sm, void *priv, struct eap_method_ret *ret,
/*
* we're buffering and this is the last fragment
*/
- if (data->in_frag_pos) {
+ if (data->in_frag_pos && data->inbuf) {
wpa_printf(MSG_DEBUG, "EAP-pwd: Last fragment, %d bytes",
(int) len);
pos = wpabuf_head_u8(data->inbuf);
diff --git a/src/eap_server/eap_server_mschapv2.c b/src/eap_server/eap_server_mschapv2.c
index 6c47bb63..e9e03b0a 100644
--- a/src/eap_server/eap_server_mschapv2.c
+++ b/src/eap_server/eap_server_mschapv2.c
@@ -551,9 +551,13 @@ static u8 * eap_mschapv2_getKey(struct eap_sm *sm, void *priv, size_t *len)
if (key == NULL)
return NULL;
/* MSK = server MS-MPPE-Recv-Key | MS-MPPE-Send-Key */
- get_asymetric_start_key(data->master_key, key, MSCHAPV2_KEY_LEN, 0, 1);
- get_asymetric_start_key(data->master_key, key + MSCHAPV2_KEY_LEN,
- MSCHAPV2_KEY_LEN, 1, 1);
+ if (get_asymetric_start_key(data->master_key, key, MSCHAPV2_KEY_LEN, 0,
+ 1) < 0 ||
+ get_asymetric_start_key(data->master_key, key + MSCHAPV2_KEY_LEN,
+ MSCHAPV2_KEY_LEN, 1, 1) < 0) {
+ os_free(key);
+ return NULL;
+ }
wpa_hexdump_key(MSG_DEBUG, "EAP-MSCHAPV2: Derived key", key, *len);
return key;
diff --git a/src/eap_server/eap_server_pwd.c b/src/eap_server/eap_server_pwd.c
index 9799c819..e720a28c 100644
--- a/src/eap_server/eap_server_pwd.c
+++ b/src/eap_server/eap_server_pwd.c
@@ -311,7 +311,7 @@ fin:
static void eap_pwd_build_confirm_req(struct eap_sm *sm,
struct eap_pwd_data *data, u8 id)
{
- struct crypto_hash *hash;
+ struct crypto_hash *hash = NULL;
u8 conf[SHA256_MAC_LEN], *cruft = NULL, *ptr;
u16 grp;
size_t prime_len, order_len;
@@ -392,6 +392,7 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm,
/* all done with the random function */
eap_pwd_h_final(hash, conf);
+ hash = NULL;
os_memcpy(data->my_confirm, conf, SHA256_MAC_LEN);
data->outbuf = wpabuf_alloc(SHA256_MAC_LEN);
@@ -404,6 +405,7 @@ fin:
bin_clear_free(cruft, prime_len * 2);
if (data->outbuf == NULL)
eap_pwd_state(data, FAILURE);
+ eap_pwd_h_final(hash, NULL);
}
@@ -648,7 +650,6 @@ eap_pwd_process_commit_resp(struct eap_sm *sm, struct eap_pwd_data *data,
const u8 *payload, size_t payload_len)
{
const u8 *ptr;
- struct crypto_bignum *cofactor = NULL;
struct crypto_ec_point *K = NULL;
int res = 0;
size_t prime_len, order_len;
@@ -667,20 +668,13 @@ eap_pwd_process_commit_resp(struct eap_sm *sm, struct eap_pwd_data *data,
}
data->k = crypto_bignum_init();
- cofactor = crypto_bignum_init();
K = crypto_ec_point_init(data->grp->group);
- if (!data->k || !cofactor || !K) {
+ if (!data->k || !K) {
wpa_printf(MSG_INFO, "EAP-PWD (server): peer data allocation "
"fail");
goto fin;
}
- if (crypto_ec_cofactor(data->grp->group, cofactor) < 0) {
- wpa_printf(MSG_INFO, "EAP-PWD (server): unable to get "
- "cofactor for curve");
- goto fin;
- }
-
/* element, x then y, followed by scalar */
ptr = payload;
data->peer_element = eap_pwd_get_element(data->grp, ptr);
@@ -718,18 +712,8 @@ eap_pwd_process_commit_resp(struct eap_sm *sm, struct eap_pwd_data *data,
goto fin;
}
- /* ensure that the shared key isn't in a small sub-group */
- if (!crypto_bignum_is_one(cofactor)) {
- if (crypto_ec_point_mul(data->grp->group, K, cofactor,
- K) != 0) {
- wpa_printf(MSG_INFO, "EAP-PWD (server): cannot "
- "multiply shared key point by order!\n");
- goto fin;
- }
- }
-
/*
- * This check is strictly speaking just for the case above where
+ * This check is strictly speaking just for the case where
* co-factor > 1 but it was suggested that even though this is probably
* never going to happen it is a simple and safe check "just to be
* sure" so let's be safe.
@@ -748,7 +732,6 @@ eap_pwd_process_commit_resp(struct eap_sm *sm, struct eap_pwd_data *data,
fin:
crypto_ec_point_deinit(K, 1);
- crypto_bignum_deinit(cofactor, 1);
if (res)
eap_pwd_state(data, PWD_Confirm_Req);
@@ -761,7 +744,7 @@ static void
eap_pwd_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data,
const u8 *payload, size_t payload_len)
{
- struct crypto_hash *hash;
+ struct crypto_hash *hash = NULL;
u32 cs;
u16 grp;
u8 conf[SHA256_MAC_LEN], *cruft = NULL, *ptr;
@@ -836,6 +819,7 @@ eap_pwd_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data,
/* all done */
eap_pwd_h_final(hash, conf);
+ hash = NULL;
ptr = (u8 *) payload;
if (os_memcmp_const(conf, ptr, SHA256_MAC_LEN)) {
@@ -855,6 +839,7 @@ eap_pwd_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data,
fin:
bin_clear_free(cruft, prime_len * 2);
+ eap_pwd_h_final(hash, NULL);
}
@@ -927,6 +912,12 @@ static void eap_pwd_process(struct eap_sm *sm, void *priv,
* the first and all intermediate fragments have the M bit set
*/
if (EAP_PWD_GET_MORE_BIT(lm_exch) || data->in_frag_pos) {
+ if (!data->inbuf) {
+ wpa_printf(MSG_DEBUG,
+ "EAP-pwd: No buffer for reassembly");
+ eap_pwd_state(data, FAILURE);
+ return;
+ }
if ((data->in_frag_pos + len) > wpabuf_size(data->inbuf)) {
wpa_printf(MSG_DEBUG, "EAP-pwd: Buffer overflow "
"attack detected! (%d+%d > %d)",
@@ -947,7 +938,7 @@ static void eap_pwd_process(struct eap_sm *sm, void *priv,
* last fragment won't have the M bit set (but we're obviously
* buffering fragments so that's how we know it's the last)
*/
- if (data->in_frag_pos) {
+ if (data->in_frag_pos && data->inbuf) {
pos = wpabuf_head_u8(data->inbuf);
len = data->in_frag_pos;
wpa_printf(MSG_DEBUG, "EAP-pwd: Last fragment, %d bytes",
@@ -1047,14 +1038,6 @@ static u8 * eap_pwd_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
int eap_server_pwd_register(void)
{
struct eap_method *eap;
- struct timeval tp;
- struct timezone tz;
- u32 sr;
-
- sr = 0xdeaddada;
- (void) gettimeofday(&tp, &tz);
- sr ^= (tp.tv_sec ^ tp.tv_usec);
- srandom(sr);
eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
EAP_VENDOR_IETF, EAP_TYPE_PWD,
diff --git a/src/pae/ieee802_1x_cp.c b/src/pae/ieee802_1x_cp.c
index 8cdce30e..1c4dc3e6 100644
--- a/src/pae/ieee802_1x_cp.c
+++ b/src/pae/ieee802_1x_cp.c
@@ -214,6 +214,10 @@ SM_STATE(CP, RECEIVE)
SM_ENTRY(CP, RECEIVE);
/* RECEIVE state machine not keep with Figure 12-2 in
* IEEE Std 802.1X-2010 */
+ if (sm->oki) {
+ ieee802_1x_kay_delete_sas(sm->kay, sm->oki);
+ os_free(sm->oki);
+ }
sm->oki = sm->lki;
sm->oan = sm->lan;
sm->otx = sm->ltx;
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index a7adbadf..66a86430 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -1021,8 +1021,6 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm,
}
os_memset(&gd, 0, sizeof(gd));
- wpa_supplicant_key_neg_complete(sm, sm->bssid,
- key_info & WPA_KEY_INFO_SECURE);
return 0;
}
@@ -1060,9 +1058,27 @@ static int wpa_supplicant_install_igtk(struct wpa_sm *sm,
broadcast_ether_addr,
keyidx, 0, igtk->pn, sizeof(igtk->pn),
igtk->igtk, len) < 0) {
- wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
- "WPA: Failed to configure IGTK to the driver");
- return -1;
+ if (keyidx == 0x0400 || keyidx == 0x0500) {
+ /* Assume the AP has broken PMF implementation since it
+ * seems to have swapped the KeyID bytes. The AP cannot
+ * be trusted to implement BIP correctly or provide a
+ * valid IGTK, so do not try to configure this key with
+ * swapped KeyID bytes. Instead, continue without
+ * configuring the IGTK so that the driver can drop any
+ * received group-addressed robust management frames due
+ * to missing keys.
+ *
+ * Normally, this error behavior would result in us
+ * disconnecting, but there are number of deployed APs
+ * with this broken behavior, so as an interoperability
+ * workaround, allow the connection to proceed. */
+ wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+ "WPA: Ignore IGTK configuration error due to invalid IGTK KeyID byte order");
+ } else {
+ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
+ "WPA: Failed to configure IGTK to the driver");
+ return -1;
+ }
}
if (wnm_sleep) {
@@ -1503,8 +1519,11 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
wpa_sm_set_state(sm, WPA_GROUP_HANDSHAKE);
if (sm->group_cipher == WPA_CIPHER_GTK_NOT_USED) {
- wpa_supplicant_key_neg_complete(sm, sm->bssid,
- key_info & WPA_KEY_INFO_SECURE);
+ /* No GTK to be set to the driver */
+ } else if (!ie.gtk && sm->proto == WPA_PROTO_RSN) {
+ wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
+ "RSN: No GTK KDE included in EAPOL-Key msg 3/4");
+ goto failed;
} else if (ie.gtk &&
wpa_supplicant_pairwise_gtk(sm, key,
ie.gtk, ie.gtk_len, key_info) < 0) {
@@ -1519,6 +1538,10 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
goto failed;
}
+ if (sm->group_cipher == WPA_CIPHER_GTK_NOT_USED || ie.gtk)
+ wpa_supplicant_key_neg_complete(sm, sm->bssid,
+ key_info & WPA_KEY_INFO_SECURE);
+
if (ie.gtk)
wpa_sm_set_rekey_offload(sm);
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 564f32b8..198ac562 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -7715,7 +7715,7 @@ static int wpas_ctrl_iface_get_pref_freq_list(
wpa_printf(MSG_DEBUG,
"CTRL_IFACE: GET_PREF_FREQ_LIST iface_type=%d (%s)",
- iface_type, buf);
+ iface_type, cmd);
ret = wpa_drv_get_pref_freq_list(wpa_s, iface_type, &num, freq_list);
if (ret)
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 632252cb..815b9947 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -2859,8 +2859,17 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
}
wpa_supplicant_cancel_scan(wpa_s);
- if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
- wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
+ if (ft_completed) {
+ /*
+ * FT protocol completed - make sure EAPOL state machine ends
+ * up in authenticated.
+ */
+ wpa_supplicant_cancel_auth_timeout(wpa_s);
+ wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
+ eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
+ eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
+ } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
+ wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
/*
* We are done; the driver will take care of RSN 4-way
* handshake.
@@ -2877,15 +2886,6 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
* waiting for WPA supplicant.
*/
eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
- } else if (ft_completed) {
- /*
- * FT protocol completed - make sure EAPOL state machine ends
- * up in authenticated.
- */
- wpa_supplicant_cancel_auth_timeout(wpa_s);
- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
- eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
- eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
}
wpa_s->last_eapol_matches_bssid = 0;
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index 44859396..9d6ab8da 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -189,7 +189,7 @@ static void mesh_mpm_init_link(struct wpa_supplicant *wpa_s,
do {
if (os_get_random((u8 *) &llid, sizeof(llid)) < 0)
- continue;
+ llid = 0; /* continue */
} while (!llid || llid_in_use(wpa_s, llid));
sta->my_lid = llid;
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 562caad5..70b61d6a 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -4198,6 +4198,9 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
return;
}
+ wpa_s->global->pending_p2ps_group = 0;
+ wpa_s->global->pending_p2ps_group_freq = 0;
+
if (conncap == P2PS_SETUP_GROUP_OWNER) {
/*
* We need to copy the interface name. Simply saving a
@@ -4208,8 +4211,10 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
go_ifname[0] = '\0';
if (!go_wpa_s) {
- wpa_s->global->pending_p2ps_group = 1;
- wpa_s->global->pending_p2ps_group_freq = freq;
+ if (!response_done) {
+ wpa_s->global->pending_p2ps_group = 1;
+ wpa_s->global->pending_p2ps_group_freq = freq;
+ }
if (!wpas_p2p_create_iface(wpa_s))
os_memcpy(go_ifname, wpa_s->ifname,
@@ -7223,7 +7228,7 @@ void wpas_p2p_completed(struct wpa_supplicant *wpa_s)
u8 go_dev_addr[ETH_ALEN];
int persistent;
int freq;
- u8 ip[3 * 4];
+ u8 ip[3 * 4], *ip_ptr = NULL;
char ip_addr[100];
if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION) {
@@ -7270,6 +7275,7 @@ void wpas_p2p_completed(struct wpa_supplicant *wpa_s)
ip[8], ip[9], ip[10], ip[11]);
if (os_snprintf_error(sizeof(ip_addr), res))
ip_addr[0] = '\0';
+ ip_ptr = ip;
}
wpas_p2p_group_started(wpa_s, 0, ssid, freq,
@@ -7282,7 +7288,7 @@ void wpas_p2p_completed(struct wpa_supplicant *wpa_s)
wpas_p2p_store_persistent_group(wpa_s->p2pdev,
ssid, go_dev_addr);
- wpas_notify_p2p_group_started(wpa_s, ssid, persistent, 1, ip);
+ wpas_notify_p2p_group_started(wpa_s, ssid, persistent, 1, ip_ptr);
}
diff --git a/wpa_supplicant/rrm.c b/wpa_supplicant/rrm.c
index ab5e6dbd..cb3c6c99 100644
--- a/wpa_supplicant/rrm.c
+++ b/wpa_supplicant/rrm.c
@@ -397,7 +397,10 @@ static int wpas_rrm_beacon_rep_update_last_frame(u8 *pos, size_t len)
struct rrm_measurement_report_element *msr_rep;
u8 *end = pos + len;
u8 *msr_rep_end;
+ struct rrm_measurement_beacon_report *rep = NULL;
+ u8 *subelem;
+ /* Find the last beacon report element */
while (end - pos >= (int) sizeof(*msr_rep)) {
msr_rep = (struct rrm_measurement_report_element *) pos;
msr_rep_end = pos + msr_rep->len + 2;
@@ -410,30 +413,27 @@ static int wpas_rrm_beacon_rep_update_last_frame(u8 *pos, size_t len)
return -1;
}
- if (msr_rep->type == MEASURE_TYPE_BEACON) {
- struct rrm_measurement_beacon_report *rep;
- u8 *subelem;
-
+ if (msr_rep->type == MEASURE_TYPE_BEACON)
rep = (struct rrm_measurement_beacon_report *)
msr_rep->variable;
- subelem = rep->variable;
- while (subelem + 2 < msr_rep_end &&
- subelem[0] !=
- WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION)
- subelem += 2 + subelem[1];
-
- if (subelem + 2 < msr_rep_end &&
- subelem[0] ==
- WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION &&
- subelem[1] == 1 &&
- subelem +
- BEACON_REPORT_LAST_INDICATION_SUBELEM_LEN <= end)
- subelem[2] = 1;
- }
pos += pos[1] + 2;
}
+ if (!rep)
+ return 0;
+
+ subelem = rep->variable;
+ while (subelem + 2 < msr_rep_end &&
+ subelem[0] != WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION)
+ subelem += 2 + subelem[1];
+
+ if (subelem + 2 < msr_rep_end &&
+ subelem[0] == WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION &&
+ subelem[1] == 1 &&
+ subelem + BEACON_REPORT_LAST_INDICATION_SUBELEM_LEN <= end)
+ subelem[2] = 1;
+
return 0;
}
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 4bb5f3ae..17a984d1 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -965,10 +965,9 @@ static void sme_send_external_auth_status(struct wpa_supplicant *wpa_s,
os_memset(&params, 0, sizeof(params));
params.status = status;
- os_memcpy(params.ssid, wpa_s->sme.ext_auth.ssid,
- wpa_s->sme.ext_auth.ssid_len);
+ params.ssid = wpa_s->sme.ext_auth.ssid;
params.ssid_len = wpa_s->sme.ext_auth.ssid_len;
- os_memcpy(params.bssid, wpa_s->sme.ext_auth.bssid, ETH_ALEN);
+ params.bssid = wpa_s->sme.ext_auth.bssid;
wpa_drv_send_external_auth_status(wpa_s, &params);
}
@@ -978,7 +977,7 @@ static void sme_handle_external_auth_start(struct wpa_supplicant *wpa_s,
{
struct wpa_ssid *ssid;
size_t ssid_str_len = data->external_auth.ssid_len;
- u8 *ssid_str = data->external_auth.ssid;
+ const u8 *ssid_str = data->external_auth.ssid;
/* Get the SSID conf from the ssid string obtained */
for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
@@ -1986,17 +1985,14 @@ void sme_clear_on_disassoc(struct wpa_supplicant *wpa_s)
if (wpa_s->sme.ft_ies || wpa_s->sme.ft_used)
sme_update_ft_ies(wpa_s, NULL, NULL, 0);
#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_IEEE80211W
+ sme_stop_sa_query(wpa_s);
+#endif /* CONFIG_IEEE80211W */
}
void sme_deinit(struct wpa_supplicant *wpa_s)
{
- os_free(wpa_s->sme.ft_ies);
- wpa_s->sme.ft_ies = NULL;
- wpa_s->sme.ft_ies_len = 0;
-#ifdef CONFIG_IEEE80211W
- sme_stop_sa_query(wpa_s);
-#endif /* CONFIG_IEEE80211W */
sme_clear_on_disassoc(wpa_s);
eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
@@ -2401,6 +2397,8 @@ static void sme_start_sa_query(struct wpa_supplicant *wpa_s)
static void sme_stop_sa_query(struct wpa_supplicant *wpa_s)
{
+ if (wpa_s->sme.sa_query_trans_id)
+ wpa_dbg(wpa_s, MSG_DEBUG, "SME: Stop SA Query");
eloop_cancel_timeout(sme_sa_query_timer, wpa_s, NULL);
os_free(wpa_s->sme.sa_query_trans_id);
wpa_s->sme.sa_query_trans_id = NULL;
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 0f7b85de..be8efb4c 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -962,7 +962,7 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
wpa_supplicant_stop_bgscan(wpa_s);
#endif /* CONFIG_BGSCAN */
- if (state == WPA_AUTHENTICATING)
+ if (state > WPA_SCANNING)
wpa_supplicant_stop_autoscan(wpa_s);
if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
@@ -2522,6 +2522,9 @@ static u8 * wpas_populate_assoc_ies(
#ifdef CONFIG_MBO
const u8 *mbo_ie;
#endif
+#ifdef CONFIG_SAE
+ int sae_pmksa_cached = 0;
+#endif /* CONFIG_SAE */
#ifdef CONFIG_FILS
const u8 *realm, *username, *rrk;
size_t realm_len, username_len, rrk_len;
@@ -2559,8 +2562,12 @@ static u8 * wpas_populate_assoc_ies(
#endif /* CONFIG_FILS */
if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
ssid, try_opportunistic,
- cache_id, 0) == 0)
+ cache_id, 0) == 0) {
eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
+#ifdef CONFIG_SAE
+ sae_pmksa_cached = 1;
+#endif /* CONFIG_SAE */
+ }
wpa_ie_len = max_wpa_ie_len;
if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
wpa_ie, &wpa_ie_len)) {
@@ -2673,6 +2680,14 @@ static u8 * wpas_populate_assoc_ies(
"Overriding auth_alg selection: 0x%x", algs);
}
+#ifdef CONFIG_SAE
+ if (sae_pmksa_cached && algs == WPA_AUTH_ALG_SAE) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "SAE: Use WPA_AUTH_ALG_OPEN for PMKSA caching attempt");
+ algs = WPA_AUTH_ALG_OPEN;
+ }
+#endif /* CONFIG_SAE */
+
#ifdef CONFIG_P2P
if (wpa_s->global->p2p) {
u8 *pos;
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index a66253fb..a9205f0b 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -318,6 +318,15 @@ fast_reauth=1
# of APs when using ap_scan=1 mode.
#bss_max_count=200
+# BSS expiration age in seconds. A BSS will be removed from the local cache
+# if it is not in use and has not been seen for this time. Default is 180.
+#bss_expiration_age=180
+
+# BSS expiration after number of scans. A BSS will be removed from the local
+# cache if it is not seen in this number of scans.
+# Default is 2.
+#bss_expiration_scan_count=2
+
# Automatic scan
# This is an optional set of parameters for automatic scanning
# within an interface in following format: