aboutsummaryrefslogtreecommitdiffstats
path: root/hostapd
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2008-08-31 19:57:28 (GMT)
committerJouni Malinen <j@w1.fi>2008-08-31 19:57:28 (GMT)
commit565861976dc4288e70eea26c9f47c6b24e25beea (patch)
treedbdbfdfd769b171d4658224191f7faa197673260 /hostapd
parent9b71728bba36effcff5c2f7fd915f5bde3753bcb (diff)
downloadhostap-565861976dc4288e70eea26c9f47c6b24e25beea.zip
hostap-565861976dc4288e70eea26c9f47c6b24e25beea.tar.gz
hostap-565861976dc4288e70eea26c9f47c6b24e25beea.tar.bz2
Added support for using SHA256-based stronger key derivation for WPA2
IEEE 802.11w/D6.0 defines new AKMPs to indicate SHA256-based algorithms for key derivation (and AES-CMAC for EAPOL-Key MIC). Add support for using new AKMPs and clean up AKMP processing with helper functions in defs.h.
Diffstat (limited to 'hostapd')
-rw-r--r--hostapd/ChangeLog2
-rw-r--r--hostapd/config.c6
-rw-r--r--hostapd/hostapd.conf3
-rw-r--r--hostapd/ieee802_1x.c13
-rw-r--r--hostapd/peerkey.c8
-rw-r--r--hostapd/pmksa_cache.c26
-rw-r--r--hostapd/pmksa_cache.h6
-rw-r--r--hostapd/wpa.c55
-rw-r--r--hostapd/wpa_auth_ie.c29
9 files changed, 99 insertions, 49 deletions
diff --git a/hostapd/ChangeLog b/hostapd/ChangeLog
index a338cdf..54045ac 100644
--- a/hostapd/ChangeLog
+++ b/hostapd/ChangeLog
@@ -13,6 +13,8 @@ ChangeLog for hostapd
* updated management frame protection to use IEEE 802.11w/D6.0
(adds a new association ping to protect against unauthenticated
authenticate or (re)associate request frames dropping association)
+ * added support for using SHA256-based stronger key derivation for WPA2
+ (IEEE 802.11w)
2008-08-10 - v0.6.4
* added peer identity into EAP-FAST PAC-Opaque and skip Phase 2
diff --git a/hostapd/config.c b/hostapd/config.c
index 0c251a9..d922962 100644
--- a/hostapd/config.c
+++ b/hostapd/config.c
@@ -817,6 +817,12 @@ static int hostapd_config_parse_key_mgmt(int line, const char *value)
else if (os_strcmp(start, "FT-EAP") == 0)
val |= WPA_KEY_MGMT_FT_IEEE8021X;
#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_IEEE80211W
+ else if (os_strcmp(start, "WPA-PSK-SHA256") == 0)
+ val |= WPA_KEY_MGMT_PSK_SHA256;
+ else if (os_strcmp(start, "WPA-EAP-SHA256") == 0)
+ val |= WPA_KEY_MGMT_IEEE8021X_SHA256;
+#endif /* CONFIG_IEEE80211W */
else {
printf("Line %d: invalid key_mgmt '%s'\n",
line, start);
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index d369c7c..75895af 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -653,7 +653,8 @@ own_ip_addr=127.0.0.1
#wpa_psk_file=/etc/hostapd.wpa_psk
# Set of accepted key management algorithms (WPA-PSK, WPA-EAP, or both). The
-# entries are separated with a space.
+# entries are separated with a space. WPA-PSK-SHA256 and WPA-EAP-SHA256 can be
+# added to enable SHA256-based stronger algorithms.
# (dot11RSNAConfigAuthenticationSuitesTable)
#wpa_key_mgmt=WPA-PSK WPA-EAP
diff --git a/hostapd/ieee802_1x.c b/hostapd/ieee802_1x.c
index a3641ba..f8e421a 100644
--- a/hostapd/ieee802_1x.c
+++ b/hostapd/ieee802_1x.c
@@ -719,8 +719,7 @@ void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,
}
if (!hapd->conf->ieee802_1x ||
- wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_PSK ||
- wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_FT_PSK)
+ wpa_key_mgmt_wpa_psk(wpa_auth_sta_key_mgmt(sta->wpa_sm)))
return;
if (!sta->eapol_sm) {
@@ -802,8 +801,7 @@ void ieee802_1x_new_station(struct hostapd_data *hapd, struct sta_info *sta)
int force_1x = 0;
if ((!force_1x && !hapd->conf->ieee802_1x) ||
- wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_PSK ||
- wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_FT_PSK)
+ wpa_key_mgmt_wpa_psk(wpa_auth_sta_key_mgmt(sta->wpa_sm)))
return;
if (sta->eapol_sm == NULL) {
@@ -1938,10 +1936,9 @@ int ieee802_1x_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
"dot1xAuthSessionTerminateCause=999\n"
"dot1xAuthSessionUserName=%s\n",
sta->acct_session_id_hi, sta->acct_session_id_lo,
- (wpa_auth_sta_key_mgmt(sta->wpa_sm) ==
- WPA_KEY_MGMT_IEEE8021X ||
- wpa_auth_sta_key_mgmt(sta->wpa_sm) ==
- WPA_KEY_MGMT_FT_IEEE8021X) ? 1 : 2,
+ (wpa_key_mgmt_wpa_ieee8021x(
+ wpa_auth_sta_key_mgmt(sta->wpa_sm))) ?
+ 1 : 2,
(unsigned int) (time(NULL) -
sta->acct_session_start),
sm->identity);
diff --git a/hostapd/peerkey.c b/hostapd/peerkey.c
index 26097b7..83f3ce5 100644
--- a/hostapd/peerkey.c
+++ b/hostapd/peerkey.c
@@ -1,6 +1,6 @@
/*
* hostapd - PeerKey for Direct Link Setup (DLS)
- * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2006-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -17,6 +17,7 @@
#include "common.h"
#include "eloop.h"
#include "sha1.h"
+#include "sha256.h"
#include "wpa.h"
#include "defs.h"
#include "wpa_auth_i.h"
@@ -309,8 +310,13 @@ void wpa_smk_m3(struct wpa_authenticator *wpa_auth,
os_memcpy(pos, kde.nonce, WPA_NONCE_LEN);
pos += WPA_NONCE_LEN;
os_memcpy(pos, key->key_nonce, WPA_NONCE_LEN);
+#ifdef CONFIG_IEEE80211W
+ sha256_prf(smk, PMK_LEN, "SMK Derivation", buf, sizeof(buf),
+ smk, PMK_LEN);
+#else /* CONFIG_IEEE80211W */
sha1_prf(smk, PMK_LEN, "SMK Derivation", buf, sizeof(buf),
smk, PMK_LEN);
+#endif /* CONFIG_IEEE80211W */
wpa_hexdump_key(MSG_DEBUG, "RSN: SMK", smk, PMK_LEN);
diff --git a/hostapd/pmksa_cache.c b/hostapd/pmksa_cache.c
index bbeb7aa..7779794 100644
--- a/hostapd/pmksa_cache.c
+++ b/hostapd/pmksa_cache.c
@@ -1,6 +1,6 @@
/*
* hostapd - PMKSA cache for IEEE 802.11i RSN
- * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -20,6 +20,7 @@
#include "common.h"
#include "eloop.h"
#include "sha1.h"
+#include "sha256.h"
#include "ieee802_1x.h"
#include "eapol_sm.h"
#include "pmksa_cache.h"
@@ -46,23 +47,29 @@ struct rsn_pmksa_cache {
* @pmk_len: Length of pmk in bytes
* @aa: Authenticator address
* @spa: Supplicant address
+ * @use_sha256: Whether to use SHA256-based KDF
*
* IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
* PMKID = HMAC-SHA1-128(PMK, "PMK Name" || AA || SPA)
*/
void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
- u8 *pmkid)
+ u8 *pmkid, int use_sha256)
{
char *title = "PMK Name";
const u8 *addr[3];
const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
- unsigned char hash[SHA1_MAC_LEN];
+ unsigned char hash[SHA256_MAC_LEN];
addr[0] = (u8 *) title;
addr[1] = aa;
addr[2] = spa;
- hmac_sha1_vector(pmk, pmk_len, 3, addr, len, hash);
+#ifdef CONFIG_IEEE80211W
+ if (use_sha256)
+ hmac_sha256_vector(pmk, pmk_len, 3, addr, len, hash);
+ else
+#endif /* CONFIG_IEEE80211W */
+ hmac_sha1_vector(pmk, pmk_len, 3, addr, len, hash);
os_memcpy(pmkid, hash, PMKID_LEN);
}
@@ -248,6 +255,7 @@ static void pmksa_cache_link_entry(struct rsn_pmksa_cache *pmksa,
* @spa: Supplicant address
* @session_timeout: Session timeout
* @eapol: Pointer to EAPOL state machine data
+ * @akmp: WPA_KEY_MGMT_* used in key derivation
* Returns: Pointer to the added PMKSA cache entry or %NULL on error
*
* This function create a PMKSA entry for a new PMK and adds it to the PMKSA
@@ -258,7 +266,7 @@ static void pmksa_cache_link_entry(struct rsn_pmksa_cache *pmksa,
struct rsn_pmksa_cache_entry *
pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
const u8 *aa, const u8 *spa, int session_timeout,
- struct eapol_state_machine *eapol)
+ struct eapol_state_machine *eapol, int akmp)
{
struct rsn_pmksa_cache_entry *entry, *pos;
struct os_time now;
@@ -271,14 +279,15 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
return NULL;
os_memcpy(entry->pmk, pmk, pmk_len);
entry->pmk_len = pmk_len;
- rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid);
+ rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid,
+ wpa_key_mgmt_sha256(akmp));
os_get_time(&now);
entry->expiration = now.sec;
if (session_timeout > 0)
entry->expiration += session_timeout;
else
entry->expiration += dot11RSNAConfigPMKLifetime;
- entry->akmp = WPA_KEY_MGMT_IEEE8021X;
+ entry->akmp = akmp;
os_memcpy(entry->spa, spa, ETH_ALEN);
pmksa_cache_from_eapol_data(entry, eapol);
@@ -412,7 +421,8 @@ struct rsn_pmksa_cache_entry * pmksa_cache_get_okc(
while (entry) {
if (os_memcmp(entry->spa, spa, ETH_ALEN) != 0)
continue;
- rsn_pmkid(entry->pmk, entry->pmk_len, aa, spa, new_pmkid);
+ rsn_pmkid(entry->pmk, entry->pmk_len, aa, spa, new_pmkid,
+ wpa_key_mgmt_sha256(entry->akmp));
if (os_memcmp(new_pmkid, pmkid, PMKID_LEN) == 0)
return entry;
entry = entry->next;
diff --git a/hostapd/pmksa_cache.h b/hostapd/pmksa_cache.h
index d5afc6f..6ba2da6 100644
--- a/hostapd/pmksa_cache.h
+++ b/hostapd/pmksa_cache.h
@@ -1,6 +1,6 @@
/*
* hostapd - PMKSA cache for IEEE 802.11i RSN
- * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -49,7 +49,7 @@ struct rsn_pmksa_cache_entry * pmksa_cache_get_okc(
struct rsn_pmksa_cache_entry *
pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
const u8 *aa, const u8 *spa, int session_timeout,
- struct eapol_state_machine *eapol);
+ struct eapol_state_machine *eapol, int akmp);
struct rsn_pmksa_cache_entry *
pmksa_cache_add_okc(struct rsn_pmksa_cache *pmksa,
const struct rsn_pmksa_cache_entry *old_entry,
@@ -57,6 +57,6 @@ pmksa_cache_add_okc(struct rsn_pmksa_cache *pmksa,
void pmksa_cache_to_eapol_data(struct rsn_pmksa_cache_entry *entry,
struct eapol_state_machine *eapol);
void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
- u8 *pmkid);
+ u8 *pmkid, int use_sha256);
#endif /* PMKSA_CACHE_H */
diff --git a/hostapd/wpa.c b/hostapd/wpa.c
index a922ae5..bee3ffa 100644
--- a/hostapd/wpa.c
+++ b/hostapd/wpa.c
@@ -21,6 +21,7 @@
#include "eapol_sm.h"
#include "wpa.h"
#include "sha1.h"
+#include "sha256.h"
#include "rc4.h"
#include "aes_wrap.h"
#include "crypto.h"
@@ -207,12 +208,16 @@ static void wpa_sta_disconnect(struct wpa_authenticator *wpa_auth,
static int wpa_use_aes_cmac(struct wpa_state_machine *sm)
{
+ int ret = 0;
#ifdef CONFIG_IEEE80211R
- return sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X ||
- sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_PSK;
-#else /* CONFIG_IEEE80211R */
- return 0;
+ if (wpa_key_mgmt_ft(sm->wpa_key_mgmt))
+ ret = 1;
#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_IEEE80211W
+ if (wpa_key_mgmt_sha256(sm->wpa_key_mgmt))
+ ret = 1;
+#endif /* CONFIG_IEEE80211W */
+ return ret;
}
@@ -847,8 +852,13 @@ static void wpa_gmk_to_gtk(const u8 *gmk, const u8 *addr, const u8 *gnonce,
os_memcpy(data, addr, ETH_ALEN);
os_memcpy(data + ETH_ALEN, gnonce, WPA_NONCE_LEN);
+#ifdef CONFIG_IEEE80211W
+ sha256_prf(gmk, WPA_GMK_LEN, "Group key expansion",
+ data, sizeof(data), gtk, gtk_len);
+#else /* CONFIG_IEEE80211W */
sha1_prf(gmk, WPA_GMK_LEN, "Group key expansion",
data, sizeof(data), gtk, gtk_len);
+#endif /* CONFIG_IEEE80211W */
wpa_hexdump_key(MSG_DEBUG, "GMK", gmk, WPA_GMK_LEN);
wpa_hexdump_key(MSG_DEBUG, "GTK", gtk, gtk_len);
@@ -1171,8 +1181,7 @@ SM_STATE(WPA_PTK, INITIALIZE)
wpa_remove_ptk(sm);
wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portValid, 0);
sm->TimeoutCtr = 0;
- if (sm->wpa_key_mgmt == WPA_KEY_MGMT_PSK ||
- sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_PSK) {
+ if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) {
wpa_auth_set_eapol(sm->wpa_auth, sm->addr,
WPA_EAPOL_authorized, 0);
}
@@ -1290,7 +1299,7 @@ SM_STATE(WPA_PTK, PTKSTART)
* one possible PSK for this STA.
*/
if (sm->wpa == WPA_VERSION_WPA2 &&
- sm->wpa_key_mgmt != WPA_KEY_MGMT_PSK) {
+ wpa_key_mgmt_wpa_ieee8021x(sm->wpa_key_mgmt)) {
pmkid = buf;
pmkid_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN;
pmkid[0] = WLAN_EID_VENDOR_SPECIFIC;
@@ -1305,7 +1314,8 @@ SM_STATE(WPA_PTK, PTKSTART)
* available with pre-calculated PMKID.
*/
rsn_pmkid(sm->PMK, PMK_LEN, sm->wpa_auth->addr,
- sm->addr, &pmkid[2 + RSN_SELECTOR_LEN]);
+ sm->addr, &pmkid[2 + RSN_SELECTOR_LEN],
+ wpa_key_mgmt_sha256(sm->wpa_key_mgmt));
}
}
wpa_send_eapol(sm->wpa_auth, sm,
@@ -1319,14 +1329,14 @@ static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *pmk,
struct wpa_ptk *ptk)
{
#ifdef CONFIG_IEEE80211R
- if (sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X ||
- sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_PSK)
+ if (wpa_key_mgmt_ft(sm->wpa_key_mgmt))
return wpa_auth_derive_ptk_ft(sm, pmk, ptk);
#endif /* CONFIG_IEEE80211R */
wpa_pmk_to_ptk(pmk, PMK_LEN, "Pairwise key expansion",
sm->wpa_auth->addr, sm->addr, sm->ANonce, sm->SNonce,
- (u8 *) ptk, sizeof(*ptk));
+ (u8 *) ptk, sizeof(*ptk),
+ wpa_key_mgmt_sha256(sm->wpa_key_mgmt));
return 0;
}
@@ -1345,8 +1355,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
* WPA-PSK: iterate through possible PSKs and select the one matching
* the packet */
for (;;) {
- if (sm->wpa_key_mgmt == WPA_KEY_MGMT_PSK ||
- sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_PSK) {
+ if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) {
pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, pmk);
if (pmk == NULL)
break;
@@ -1361,8 +1370,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
break;
}
- if (sm->wpa_key_mgmt != WPA_KEY_MGMT_PSK &&
- sm->wpa_key_mgmt != WPA_KEY_MGMT_FT_PSK)
+ if (!wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt))
break;
}
@@ -1374,8 +1382,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
eloop_cancel_timeout(wpa_send_eapol_timeout, sm->wpa_auth, sm);
- if (sm->wpa_key_mgmt == WPA_KEY_MGMT_PSK ||
- sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_PSK) {
+ if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) {
/* PSK may have changed from the previous choice, so update
* state machine data based on whatever PSK was selected here.
*/
@@ -1537,8 +1544,7 @@ SM_STATE(WPA_PTK, PTKINITDONE)
/* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
sm->pairwise_set = TRUE;
- if (sm->wpa_key_mgmt == WPA_KEY_MGMT_PSK ||
- sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_PSK) {
+ if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) {
wpa_auth_set_eapol(sm->wpa_auth, sm->addr,
WPA_EAPOL_authorized, 1);
}
@@ -1600,13 +1606,11 @@ SM_STEP(WPA_PTK)
SM_ENTER(WPA_PTK, AUTHENTICATION2);
break;
case WPA_PTK_AUTHENTICATION2:
- if ((sm->wpa_key_mgmt == WPA_KEY_MGMT_IEEE8021X ||
- sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) &&
+ if (wpa_key_mgmt_wpa_ieee8021x(sm->wpa_key_mgmt) &&
wpa_auth_get_eapol(sm->wpa_auth, sm->addr,
WPA_EAPOL_keyRun) > 0)
SM_ENTER(WPA_PTK, INITPMK);
- else if ((sm->wpa_key_mgmt == WPA_KEY_MGMT_PSK ||
- sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_PSK)
+ else if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)
/* FIX: && 802.1X::keyRun */)
SM_ENTER(WPA_PTK, INITPSK);
break;
@@ -2252,7 +2256,7 @@ int wpa_auth_pmksa_add(struct wpa_state_machine *sm, const u8 *pmk,
if (pmksa_cache_add(sm->wpa_auth->pmksa, pmk, PMK_LEN,
sm->wpa_auth->addr, sm->addr, session_timeout,
- eapol))
+ eapol, sm->wpa_key_mgmt))
return 0;
return -1;
@@ -2268,7 +2272,8 @@ int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth,
return -1;
if (pmksa_cache_add(wpa_auth->pmksa, pmk, len, wpa_auth->addr,
- sta_addr, session_timeout, eapol))
+ sta_addr, session_timeout, eapol,
+ WPA_KEY_MGMT_IEEE8021X))
return 0;
return -1;
diff --git a/hostapd/wpa_auth_ie.c b/hostapd/wpa_auth_ie.c
index 78b0693..3f6551f 100644
--- a/hostapd/wpa_auth_ie.c
+++ b/hostapd/wpa_auth_ie.c
@@ -1,6 +1,6 @@
/*
* hostapd - WPA/RSN IE and KDE definitions
- * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -189,6 +189,18 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
num_suites++;
}
#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_IEEE80211W
+ if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
+ RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA256);
+ pos += RSN_SELECTOR_LEN;
+ num_suites++;
+ }
+ if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
+ RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_SHA256);
+ pos += RSN_SELECTOR_LEN;
+ num_suites++;
+ }
+#endif /* CONFIG_IEEE80211W */
if (num_suites == 0) {
wpa_printf(MSG_DEBUG, "Invalid key management type (%d).",
@@ -470,6 +482,12 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
else if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK)
selector = RSN_AUTH_KEY_MGMT_FT_PSK;
#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_IEEE80211W
+ else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
+ selector = RSN_AUTH_KEY_MGMT_802_1X_SHA256;
+ else if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
+ selector = RSN_AUTH_KEY_MGMT_PSK_SHA256;
+#endif /* CONFIG_IEEE80211W */
else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X)
selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
else if (data.key_mgmt & WPA_KEY_MGMT_PSK)
@@ -564,6 +582,12 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
else if (key_mgmt & WPA_KEY_MGMT_FT_PSK)
sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_PSK;
#endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_IEEE80211W
+ else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
+ sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
+ else if (key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
+ sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
+#endif /* CONFIG_IEEE80211W */
else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X)
sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X;
else
@@ -610,8 +634,7 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_IEEE80211R
- if (sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X ||
- sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_PSK) {
+ if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
if (mdie == NULL || mdie_len < MOBILITY_DOMAIN_ID_LEN + 1) {
wpa_printf(MSG_DEBUG, "RSN: Trying to use FT, but "
"MDIE not included");