|
@@ -21,6 +21,7 @@
|
|
#include "eapol_sm.h"
|
|
#include "eapol_sm.h"
|
|
#include "wpa.h"
|
|
#include "wpa.h"
|
|
#include "sha1.h"
|
|
#include "sha1.h"
|
|
|
|
+#include "sha256.h"
|
|
#include "rc4.h"
|
|
#include "rc4.h"
|
|
#include "aes_wrap.h"
|
|
#include "aes_wrap.h"
|
|
#include "crypto.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)
|
|
static int wpa_use_aes_cmac(struct wpa_state_machine *sm)
|
|
{
|
|
{
|
|
|
|
+ int ret = 0;
|
|
#ifdef CONFIG_IEEE80211R
|
|
#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 */
|
|
#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, addr, ETH_ALEN);
|
|
os_memcpy(data + ETH_ALEN, gnonce, WPA_NONCE_LEN);
|
|
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",
|
|
sha1_prf(gmk, WPA_GMK_LEN, "Group key expansion",
|
|
data, sizeof(data), gtk, gtk_len);
|
|
data, sizeof(data), gtk, gtk_len);
|
|
|
|
+#endif /* CONFIG_IEEE80211W */
|
|
|
|
|
|
wpa_hexdump_key(MSG_DEBUG, "GMK", gmk, WPA_GMK_LEN);
|
|
wpa_hexdump_key(MSG_DEBUG, "GMK", gmk, WPA_GMK_LEN);
|
|
wpa_hexdump_key(MSG_DEBUG, "GTK", gtk, gtk_len);
|
|
wpa_hexdump_key(MSG_DEBUG, "GTK", gtk, gtk_len);
|
|
@@ -1171,8 +1181,7 @@ SM_STATE(WPA_PTK, INITIALIZE)
|
|
wpa_remove_ptk(sm);
|
|
wpa_remove_ptk(sm);
|
|
wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portValid, 0);
|
|
wpa_auth_set_eapol(sm->wpa_auth, sm->addr, WPA_EAPOL_portValid, 0);
|
|
sm->TimeoutCtr = 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_auth_set_eapol(sm->wpa_auth, sm->addr,
|
|
WPA_EAPOL_authorized, 0);
|
|
WPA_EAPOL_authorized, 0);
|
|
}
|
|
}
|
|
@@ -1290,7 +1299,7 @@ SM_STATE(WPA_PTK, PTKSTART)
|
|
* one possible PSK for this STA.
|
|
* one possible PSK for this STA.
|
|
*/
|
|
*/
|
|
if (sm->wpa == WPA_VERSION_WPA2 &&
|
|
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 = buf;
|
|
pmkid_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN;
|
|
pmkid_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN;
|
|
pmkid[0] = WLAN_EID_VENDOR_SPECIFIC;
|
|
pmkid[0] = WLAN_EID_VENDOR_SPECIFIC;
|
|
@@ -1305,7 +1314,8 @@ SM_STATE(WPA_PTK, PTKSTART)
|
|
* available with pre-calculated PMKID.
|
|
* available with pre-calculated PMKID.
|
|
*/
|
|
*/
|
|
rsn_pmkid(sm->PMK, PMK_LEN, sm->wpa_auth->addr,
|
|
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,
|
|
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)
|
|
struct wpa_ptk *ptk)
|
|
{
|
|
{
|
|
#ifdef CONFIG_IEEE80211R
|
|
#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);
|
|
return wpa_auth_derive_ptk_ft(sm, pmk, ptk);
|
|
#endif /* CONFIG_IEEE80211R */
|
|
#endif /* CONFIG_IEEE80211R */
|
|
|
|
|
|
wpa_pmk_to_ptk(pmk, PMK_LEN, "Pairwise key expansion",
|
|
wpa_pmk_to_ptk(pmk, PMK_LEN, "Pairwise key expansion",
|
|
sm->wpa_auth->addr, sm->addr, sm->ANonce, sm->SNonce,
|
|
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;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -1345,8 +1355,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
|
|
* WPA-PSK: iterate through possible PSKs and select the one matching
|
|
* WPA-PSK: iterate through possible PSKs and select the one matching
|
|
* the packet */
|
|
* the packet */
|
|
for (;;) {
|
|
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);
|
|
pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr, pmk);
|
|
if (pmk == NULL)
|
|
if (pmk == NULL)
|
|
break;
|
|
break;
|
|
@@ -1361,8 +1370,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
|
|
break;
|
|
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;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1374,8 +1382,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
|
|
|
|
|
|
eloop_cancel_timeout(wpa_send_eapol_timeout, sm->wpa_auth, sm);
|
|
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
|
|
/* PSK may have changed from the previous choice, so update
|
|
* state machine data based on whatever PSK was selected here.
|
|
* 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) */
|
|
/* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */
|
|
sm->pairwise_set = TRUE;
|
|
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_auth_set_eapol(sm->wpa_auth, sm->addr,
|
|
WPA_EAPOL_authorized, 1);
|
|
WPA_EAPOL_authorized, 1);
|
|
}
|
|
}
|
|
@@ -1600,13 +1606,11 @@ SM_STEP(WPA_PTK)
|
|
SM_ENTER(WPA_PTK, AUTHENTICATION2);
|
|
SM_ENTER(WPA_PTK, AUTHENTICATION2);
|
|
break;
|
|
break;
|
|
case WPA_PTK_AUTHENTICATION2:
|
|
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_auth_get_eapol(sm->wpa_auth, sm->addr,
|
|
WPA_EAPOL_keyRun) > 0)
|
|
WPA_EAPOL_keyRun) > 0)
|
|
SM_ENTER(WPA_PTK, INITPMK);
|
|
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 */)
|
|
/* FIX: && 802.1X::keyRun */)
|
|
SM_ENTER(WPA_PTK, INITPSK);
|
|
SM_ENTER(WPA_PTK, INITPSK);
|
|
break;
|
|
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,
|
|
if (pmksa_cache_add(sm->wpa_auth->pmksa, pmk, PMK_LEN,
|
|
sm->wpa_auth->addr, sm->addr, session_timeout,
|
|
sm->wpa_auth->addr, sm->addr, session_timeout,
|
|
- eapol))
|
|
|
|
|
|
+ eapol, sm->wpa_key_mgmt))
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
return -1;
|
|
return -1;
|
|
@@ -2268,7 +2272,8 @@ int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth,
|
|
return -1;
|
|
return -1;
|
|
|
|
|
|
if (pmksa_cache_add(wpa_auth->pmksa, pmk, len, wpa_auth->addr,
|
|
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 0;
|
|
|
|
|
|
return -1;
|
|
return -1;
|