Fix SAE state validation on AP
Confirm-before-commit validation step allowed execution to continue on error case. This could result in segfault in sae_check_confirm() if the temporary SAE data was not available (as it would not be, e.g., in case of an extra SAE confirm message being received after successful exchange). Fix this by stopping SAE processing immediately after detecting unexpected state for confirm message. In addition, make the public sae.c functions verify sae->tmp before dereferencing it to make this type of bugs less likely to result in critical issues. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
d6bfaaac69
commit
b64afe22aa
2 changed files with 18 additions and 1 deletions
|
@ -471,6 +471,7 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
|
|||
HOSTAPD_LEVEL_DEBUG,
|
||||
"SAE confirm before commit");
|
||||
resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
|
||||
goto failed;
|
||||
}
|
||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
|
||||
HOSTAPD_LEVEL_DEBUG,
|
||||
|
@ -502,6 +503,7 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
|
|||
resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
|
||||
}
|
||||
|
||||
failed:
|
||||
sta->auth_alg = WLAN_AUTH_SAE;
|
||||
|
||||
send_auth_reply(hapd, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
|
||||
|
|
|
@ -503,6 +503,8 @@ int sae_prepare_commit(const u8 *addr1, const u8 *addr2,
|
|||
const u8 *password, size_t password_len,
|
||||
struct sae_data *sae)
|
||||
{
|
||||
if (sae->tmp == NULL)
|
||||
return -1;
|
||||
if (sae->tmp->ec && sae_derive_pwe_ecc(sae, addr1, addr2, password,
|
||||
password_len) < 0)
|
||||
return -1;
|
||||
|
@ -634,7 +636,8 @@ fail:
|
|||
int sae_process_commit(struct sae_data *sae)
|
||||
{
|
||||
u8 k[SAE_MAX_PRIME_LEN];
|
||||
if ((sae->tmp->ec && sae_derive_k_ecc(sae, k) < 0) ||
|
||||
if (sae->tmp == NULL ||
|
||||
(sae->tmp->ec && sae_derive_k_ecc(sae, k) < 0) ||
|
||||
(sae->tmp->dh && sae_derive_k_ffc(sae, k) < 0) ||
|
||||
sae_derive_keys(sae, k) < 0)
|
||||
return -1;
|
||||
|
@ -646,6 +649,10 @@ void sae_write_commit(struct sae_data *sae, struct wpabuf *buf,
|
|||
const struct wpabuf *token)
|
||||
{
|
||||
u8 *pos;
|
||||
|
||||
if (sae->tmp == NULL)
|
||||
return;
|
||||
|
||||
wpabuf_put_le16(buf, sae->group); /* Finite Cyclic Group */
|
||||
if (token)
|
||||
wpabuf_put_buf(buf, token);
|
||||
|
@ -990,6 +997,9 @@ void sae_write_confirm(struct sae_data *sae, struct wpabuf *buf)
|
|||
{
|
||||
const u8 *sc;
|
||||
|
||||
if (sae->tmp == NULL)
|
||||
return;
|
||||
|
||||
/* Send-Confirm */
|
||||
sc = wpabuf_put(buf, 0);
|
||||
wpabuf_put_le16(buf, sae->send_confirm);
|
||||
|
@ -1021,6 +1031,11 @@ int sae_check_confirm(struct sae_data *sae, const u8 *data, size_t len)
|
|||
|
||||
wpa_printf(MSG_DEBUG, "SAE: peer-send-confirm %u", WPA_GET_LE16(data));
|
||||
|
||||
if (sae->tmp == NULL) {
|
||||
wpa_printf(MSG_DEBUG, "SAE: Temporary data not yet available");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sae->tmp->ec)
|
||||
sae_cn_confirm_ecc(sae, data, sae->peer_commit_scalar,
|
||||
sae->tmp->peer_commit_element_ecc,
|
||||
|
|
Loading…
Reference in a new issue