aboutsummaryrefslogtreecommitdiffstats
path: root/hostapd/wpa.c
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/wpa.c
parent9b71728bba36effcff5c2f7fd915f5bde3753bcb (diff)
downloadhostap-06-565861976dc4288e70eea26c9f47c6b24e25beea.zip
hostap-06-565861976dc4288e70eea26c9f47c6b24e25beea.tar.gz
hostap-06-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/wpa.c')
-rw-r--r--hostapd/wpa.c55
1 files changed, 30 insertions, 25 deletions
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;