FILS: Move authentication response handling into a helper function

This can be reused when splitting handle_auth_fils() to support the
driver-based AP SME case.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jeffin Mammen 2017-04-21 18:42:00 +03:00 committed by Jouni Malinen
parent b8a3453aca
commit 5e5f8c816b

View File

@ -48,6 +48,16 @@
#include "fils_hlp.h" #include "fils_hlp.h"
#ifdef CONFIG_FILS
static struct wpabuf *
prepare_auth_resp_fils(struct hostapd_data *hapd,
struct sta_info *sta, u16 *resp,
struct rsn_pmksa_cache_entry *pmksa,
struct wpabuf *erp_resp,
const u8 *msk, size_t msk_len,
int *is_pub);
#endif /* CONFIG_FILS */
u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid) u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
{ {
u8 *pos = eid; u8 *pos = eid;
@ -1223,11 +1233,13 @@ fail:
} }
static void handle_auth_fils_finish(struct hostapd_data *hapd, static struct wpabuf *
struct sta_info *sta, u16 resp, prepare_auth_resp_fils(struct hostapd_data *hapd,
struct rsn_pmksa_cache_entry *pmksa, struct sta_info *sta, u16 *resp,
struct wpabuf *erp_resp, struct rsn_pmksa_cache_entry *pmksa,
const u8 *msk, size_t msk_len) struct wpabuf *erp_resp,
const u8 *msk, size_t msk_len,
int *is_pub)
{ {
u8 fils_nonce[FILS_NONCE_LEN]; u8 fils_nonce[FILS_NONCE_LEN];
size_t ielen; size_t ielen;
@ -1238,33 +1250,34 @@ static void handle_auth_fils_finish(struct hostapd_data *hapd,
size_t pmk_len = 0; size_t pmk_len = 0;
u8 pmk_buf[PMK_LEN_MAX]; u8 pmk_buf[PMK_LEN_MAX];
struct wpabuf *pub = NULL; struct wpabuf *pub = NULL;
u16 auth_alg;
if (resp != WLAN_STATUS_SUCCESS) if (*resp != WLAN_STATUS_SUCCESS)
goto fail; goto fail;
ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ielen); ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ielen);
if (!ie) { if (!ie) {
resp = WLAN_STATUS_UNSPECIFIED_FAILURE; *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto fail; goto fail;
} }
if (pmksa) { if (pmksa) {
/* Add PMKID of the selected PMKSA into RSNE */ /* Add PMKID of the selected PMKSA into RSNE */
ie_buf = os_malloc(ielen + 2 + 2 + PMKID_LEN); ie_buf = os_malloc(ielen + 2 + 2 + PMKID_LEN);
if (!ie_buf) { if (!ie_buf) {
resp = WLAN_STATUS_UNSPECIFIED_FAILURE; *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto fail; goto fail;
} }
os_memcpy(ie_buf, ie, ielen); os_memcpy(ie_buf, ie, ielen);
if (wpa_insert_pmkid(ie_buf, &ielen, pmksa->pmkid) < 0) { if (wpa_insert_pmkid(ie_buf, &ielen, pmksa->pmkid) < 0) {
resp = WLAN_STATUS_UNSPECIFIED_FAILURE; *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto fail; goto fail;
} }
ie = ie_buf; ie = ie_buf;
} }
if (random_get_bytes(fils_nonce, FILS_NONCE_LEN) < 0) { if (random_get_bytes(fils_nonce, FILS_NONCE_LEN) < 0) {
resp = WLAN_STATUS_UNSPECIFIED_FAILURE; *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto fail; goto fail;
} }
wpa_hexdump(MSG_DEBUG, "RSN: Generated FILS Nonce", wpa_hexdump(MSG_DEBUG, "RSN: Generated FILS Nonce",
@ -1274,7 +1287,7 @@ static void handle_auth_fils_finish(struct hostapd_data *hapd,
if (sta->fils_dh_ss && sta->fils_ecdh) { if (sta->fils_dh_ss && sta->fils_ecdh) {
pub = crypto_ecdh_get_pubkey(sta->fils_ecdh, 1); pub = crypto_ecdh_get_pubkey(sta->fils_ecdh, 1);
if (!pub) { if (!pub) {
resp = WLAN_STATUS_UNSPECIFIED_FAILURE; *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto fail; goto fail;
} }
} }
@ -1282,7 +1295,7 @@ static void handle_auth_fils_finish(struct hostapd_data *hapd,
data = wpabuf_alloc(1000 + ielen + (pub ? wpabuf_len(pub) : 0)); data = wpabuf_alloc(1000 + ielen + (pub ? wpabuf_len(pub) : 0));
if (!data) { if (!data) {
resp = WLAN_STATUS_UNSPECIFIED_FAILURE; *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto fail; goto fail;
} }
@ -1310,7 +1323,7 @@ static void handle_auth_fils_finish(struct hostapd_data *hapd,
res = wpa_auth_write_fte(hapd->wpa_auth, wpabuf_put(data, 0), res = wpa_auth_write_fte(hapd->wpa_auth, wpabuf_put(data, 0),
wpabuf_tailroom(data)); wpabuf_tailroom(data));
if (res < 0) { if (res < 0) {
resp = WLAN_STATUS_UNSPECIFIED_FAILURE; *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto fail; goto fail;
} }
wpabuf_put(data, res); wpabuf_put(data, res);
@ -1347,7 +1360,7 @@ static void handle_auth_fils_finish(struct hostapd_data *hapd,
wpabuf_len(sta->fils_dh_ss) : 0, wpabuf_len(sta->fils_dh_ss) : 0,
pmk_buf, &pmk_len)) { pmk_buf, &pmk_len)) {
wpa_printf(MSG_DEBUG, "FILS: Failed to derive PMK"); wpa_printf(MSG_DEBUG, "FILS: Failed to derive PMK");
resp = WLAN_STATUS_UNSPECIFIED_FAILURE; *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
wpabuf_free(data); wpabuf_free(data);
data = NULL; data = NULL;
goto fail; goto fail;
@ -1360,7 +1373,7 @@ static void handle_auth_fils_finish(struct hostapd_data *hapd,
if (!pmk) { if (!pmk) {
wpa_printf(MSG_DEBUG, "FILS: No PMK available"); wpa_printf(MSG_DEBUG, "FILS: No PMK available");
resp = WLAN_STATUS_UNSPECIFIED_FAILURE; *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
wpabuf_free(data); wpabuf_free(data);
data = NULL; data = NULL;
goto fail; goto fail;
@ -1368,13 +1381,43 @@ static void handle_auth_fils_finish(struct hostapd_data *hapd,
if (fils_auth_pmk_to_ptk(sta->wpa_sm, pmk, pmk_len, if (fils_auth_pmk_to_ptk(sta->wpa_sm, pmk, pmk_len,
sta->fils_snonce, fils_nonce) < 0) { sta->fils_snonce, fils_nonce) < 0) {
resp = WLAN_STATUS_UNSPECIFIED_FAILURE; *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
wpabuf_free(data); wpabuf_free(data);
data = NULL; data = NULL;
goto fail; goto fail;
} }
fail: fail:
if (is_pub)
*is_pub = pub != NULL;
os_free(ie_buf);
wpabuf_free(pub);
wpabuf_clear_free(sta->fils_dh_ss);
sta->fils_dh_ss = NULL;
#ifdef CONFIG_FILS_SK_PFS
crypto_ecdh_deinit(sta->fils_ecdh);
sta->fils_ecdh = NULL;
#endif /* CONFIG_FILS_SK_PFS */
return data;
}
static void handle_auth_fils_finish(struct hostapd_data *hapd,
struct sta_info *sta, u16 resp,
struct rsn_pmksa_cache_entry *pmksa,
struct wpabuf *erp_resp,
const u8 *msk, size_t msk_len)
{
struct wpabuf *data;
u16 auth_alg;
int pub = 0;
data = prepare_auth_resp_fils(hapd, sta, &resp, pmksa, erp_resp,
msk, msk_len, &pub);
if (!data)
wpa_printf(MSG_DEBUG, "%s: prepare_auth_resp returned failure",
__func__);
auth_alg = (pub || auth_alg = (pub ||
resp == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED) ? resp == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED) ?
WLAN_AUTH_FILS_SK_PFS : WLAN_AUTH_FILS_SK; WLAN_AUTH_FILS_SK_PFS : WLAN_AUTH_FILS_SK;
@ -1392,15 +1435,6 @@ fail:
sta->auth_alg = pub ? WLAN_AUTH_FILS_SK_PFS : WLAN_AUTH_FILS_SK; sta->auth_alg = pub ? WLAN_AUTH_FILS_SK_PFS : WLAN_AUTH_FILS_SK;
mlme_authenticate_indication(hapd, sta); mlme_authenticate_indication(hapd, sta);
} }
os_free(ie_buf);
wpabuf_free(pub);
wpabuf_clear_free(sta->fils_dh_ss);
sta->fils_dh_ss = NULL;
#ifdef CONFIG_FILS_SK_PFS
crypto_ecdh_deinit(sta->fils_ecdh);
sta->fils_ecdh = NULL;
#endif /* CONFIG_FILS_SK_PFS */
} }