aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2005-06-24 05:04:26 (GMT)
committerJouni Malinen <j@w1.fi>2005-06-24 05:04:26 (GMT)
commit2af2a613bfdc7a2033e722e99a236974d79d8cf0 (patch)
tree4f0513ccba0111f0b61fa8898a2a4b404c62609f
parentdd860fc523c0829257871f8fa0e67984e0f19b7c (diff)
downloadhostap-history-2af2a613bfdc7a2033e722e99a236974d79d8cf0.zip
hostap-history-2af2a613bfdc7a2033e722e99a236974d79d8cf0.tar.gz
hostap-history-2af2a613bfdc7a2033e722e99a236974d79d8cf0.tar.bz2
WPA state machine separation changes:
- Moved wpa_s->proto into wpa_s->wpa->proto - Copy wpa_s->{pairwise_cipher,group_cipher,key_mgmt} into wpa_s->wpa - Moved WPA specific status functions from ctrl_iface.c and config.c into wpa.c
-rw-r--r--wpa_supplicant/config.c49
-rw-r--r--wpa_supplicant/config_ssid.h2
-rw-r--r--wpa_supplicant/ctrl_iface.c15
-rw-r--r--wpa_supplicant/preauth.c6
-rw-r--r--wpa_supplicant/wpa.c271
-rw-r--r--wpa_supplicant/wpa.h14
-rw-r--r--wpa_supplicant/wpa_i.h6
-rw-r--r--wpa_supplicant/wpa_supplicant.c18
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h1
9 files changed, 237 insertions, 145 deletions
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 0ec67a6..e611044 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -1086,52 +1086,3 @@ int wpa_config_allowed_eap_method(struct wpa_ssid *ssid, int method)
}
return 0;
}
-
-
-/**
- * wpa_cipher_txt - Convert cipher suite to a text string
- * @cipher: Cipher suite (WPA_CIPHER_* enum)
- * Returns: Pointer to a text string of the cipher suite name
- */
-const char * wpa_cipher_txt(int cipher)
-{
- switch (cipher) {
- case WPA_CIPHER_NONE:
- return "NONE";
- case WPA_CIPHER_WEP40:
- return "WEP-40";
- case WPA_CIPHER_WEP104:
- return "WEP-104";
- case WPA_CIPHER_TKIP:
- return "TKIP";
- case WPA_CIPHER_CCMP:
- return "CCMP";
- default:
- return "UNKNOWN";
- }
-}
-
-
-/**
- * wpa_key_mgmt_txt - Convert key management suite to a text string
- * @key_mgmt: Key management suite (WPA_KEY_MGMT_* enum)
- * @proto: WPA/WPA2 version (WPA_PROTO_*)
- * Returns: Pointer to a text string of the key management suite name
- */
-const char * wpa_key_mgmt_txt(int key_mgmt, int proto)
-{
- switch (key_mgmt) {
- case WPA_KEY_MGMT_IEEE8021X:
- return proto == WPA_PROTO_RSN ?
- "WPA2/IEEE 802.1X/EAP" : "WPA/IEEE 802.1X/EAP";
- case WPA_KEY_MGMT_PSK:
- return proto == WPA_PROTO_RSN ?
- "WPA2-PSK" : "WPA-PSK";
- case WPA_KEY_MGMT_NONE:
- return "NONE";
- case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
- return "IEEE 802.1X (no WPA)";
- default:
- return "UNKNOWN";
- }
-}
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index 4a89dba..53a9edf 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -163,7 +163,5 @@ struct wpa_ssid {
};
int wpa_config_allowed_eap_method(struct wpa_ssid *ssid, int method);
-const char * wpa_cipher_txt(int cipher);
-const char * wpa_key_mgmt_txt(int key_mgmt, int proto);
#endif /* CONFIG_SSID_H */
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index f5e7825..9ff76b5 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -90,15 +90,15 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
eapol_sm_configure(wpa_s->eapol,
-1, -1, -1, atoi(value));
} else if (strcasecmp(cmd, "dot11RSNAConfigPMKLifetime") == 0) {
- if (wpa_sm_configure(wpa_s->wpa, RSNA_PMK_LIFETIME,
+ if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
atoi(value)))
ret = -1;
} else if (strcasecmp(cmd, "dot11RSNAConfigPMKReauthThreshold") == 0) {
- if (wpa_sm_configure(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
+ if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
atoi(value)))
ret = -1;
} else if (strcasecmp(cmd, "dot11RSNAConfigSATimeout") == 0) {
- if (wpa_sm_configure(wpa_s->wpa, RSNA_SA_TIMEOUT, atoi(value)))
+ if (wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, atoi(value)))
ret = -1;
} else
ret = -1;
@@ -333,14 +333,7 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
ssid_len));
}
- pos += snprintf(pos, end - pos,
- "pairwise_cipher=%s\n"
- "group_cipher=%s\n"
- "key_mgmt=%s\n",
- wpa_cipher_txt(wpa_s->pairwise_cipher),
- wpa_cipher_txt(wpa_s->group_cipher),
- wpa_key_mgmt_txt(wpa_s->key_mgmt,
- wpa_s->proto));
+ pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose);
}
pos += snprintf(pos, end - pos, "wpa_state=%s\n",
wpa_supplicant_state_txt(wpa_s->wpa_state));
diff --git a/wpa_supplicant/preauth.c b/wpa_supplicant/preauth.c
index 78ec7c0..bd90e76 100644
--- a/wpa_supplicant/preauth.c
+++ b/wpa_supplicant/preauth.c
@@ -172,7 +172,7 @@ pmksa_cache_add(struct wpa_sm *sm, const u8 *pmk,
struct wpa_supplicant *wpa_s = sm->ctx;
time_t now;
- if (wpa_s->proto != WPA_PROTO_RSN || pmk_len > PMK_LEN)
+ if (sm->proto != WPA_PROTO_RSN || pmk_len > PMK_LEN)
return NULL;
entry = malloc(sizeof(*entry));
@@ -698,9 +698,9 @@ void rsn_preauth_candidate_process(struct wpa_sm *sm)
wpa_msg(sm->ctx, MSG_DEBUG, "RSN: processing PMKSA candidate list");
if (sm->preauth_eapol ||
- wpa_s->proto != WPA_PROTO_RSN ||
+ sm->proto != WPA_PROTO_RSN ||
wpa_s->wpa_state != WPA_COMPLETED ||
- wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X) {
+ sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X) {
wpa_msg(sm->ctx, MSG_DEBUG, "RSN: not in suitable state for "
"new pre-authentication");
return; /* invalid state for new pre-auth */
diff --git a/wpa_supplicant/wpa.c b/wpa_supplicant/wpa.c
index 4f5ec38..f390a36 100644
--- a/wpa_supplicant/wpa.c
+++ b/wpa_supplicant/wpa.c
@@ -121,6 +121,57 @@ struct rsn_ie_hdr {
} __attribute__ ((packed));
+
+
+/**
+ * wpa_cipher_txt - Convert cipher suite to a text string
+ * @cipher: Cipher suite (WPA_CIPHER_* enum)
+ * Returns: Pointer to a text string of the cipher suite name
+ */
+static const char * wpa_cipher_txt(int cipher)
+{
+ switch (cipher) {
+ case WPA_CIPHER_NONE:
+ return "NONE";
+ case WPA_CIPHER_WEP40:
+ return "WEP-40";
+ case WPA_CIPHER_WEP104:
+ return "WEP-104";
+ case WPA_CIPHER_TKIP:
+ return "TKIP";
+ case WPA_CIPHER_CCMP:
+ return "CCMP";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+
+/**
+ * wpa_key_mgmt_txt - Convert key management suite to a text string
+ * @key_mgmt: Key management suite (WPA_KEY_MGMT_* enum)
+ * @proto: WPA/WPA2 version (WPA_PROTO_*)
+ * Returns: Pointer to a text string of the key management suite name
+ */
+static const char * wpa_key_mgmt_txt(int key_mgmt, int proto)
+{
+ switch (key_mgmt) {
+ case WPA_KEY_MGMT_IEEE8021X:
+ return proto == WPA_PROTO_RSN ?
+ "WPA2/IEEE 802.1X/EAP" : "WPA/IEEE 802.1X/EAP";
+ case WPA_KEY_MGMT_PSK:
+ return proto == WPA_PROTO_RSN ?
+ "WPA2-PSK" : "WPA-PSK";
+ case WPA_KEY_MGMT_NONE:
+ return "NONE";
+ case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
+ return "IEEE 802.1X (no WPA)";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+
static int wpa_selector_to_bitfield(const u8 *s)
{
if (memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN) == 0)
@@ -593,16 +644,17 @@ static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
*/
int wpa_gen_wpa_ie(struct wpa_supplicant *wpa_s, u8 *wpa_ie, size_t wpa_ie_len)
{
- if (wpa_s->proto == WPA_PROTO_RSN)
+ struct wpa_sm *sm = wpa_s->wpa;
+ if (sm->proto == WPA_PROTO_RSN)
return wpa_gen_wpa_ie_rsn(wpa_ie, wpa_ie_len,
- wpa_s->pairwise_cipher,
- wpa_s->group_cipher,
- wpa_s->key_mgmt, wpa_s->wpa);
+ sm->pairwise_cipher,
+ sm->group_cipher,
+ sm->key_mgmt, wpa_s->wpa);
else
return wpa_gen_wpa_ie_wpa(wpa_ie, wpa_ie_len,
- wpa_s->pairwise_cipher,
- wpa_s->group_cipher,
- wpa_s->key_mgmt);
+ sm->pairwise_cipher,
+ sm->group_cipher,
+ sm->key_mgmt);
}
@@ -721,7 +773,7 @@ void wpa_supplicant_key_request(struct wpa_supplicant *wpa_s,
int key_info, ver;
u8 bssid[ETH_ALEN], *rbuf;
- if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP)
+ if (sm->pairwise_cipher == WPA_CIPHER_CCMP)
ver = WPA_KEY_INFO_TYPE_HMAC_SHA1_AES;
else
ver = WPA_KEY_INFO_TYPE_HMAC_MD5_RC4;
@@ -738,7 +790,7 @@ void wpa_supplicant_key_request(struct wpa_supplicant *wpa_s,
if (rbuf == NULL)
return;
- reply->type = wpa_s->proto == WPA_PROTO_RSN ?
+ reply->type = sm->proto == WPA_PROTO_RSN ?
EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
key_info = WPA_KEY_INFO_REQUEST | ver;
if (sm->ptk_set)
@@ -888,7 +940,7 @@ static int wpa_supplicant_get_pmk(struct wpa_supplicant *wpa_s,
wpa_hexdump_key(MSG_DEBUG, "RSN: PMK from PMKSA cache",
sm->pmk, sm->pmk_len);
eapol_sm_notify_cached(wpa_s->eapol);
- } else if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X && wpa_s->eapol) {
+ } else if (sm->key_mgmt == WPA_KEY_MGMT_IEEE8021X && wpa_s->eapol) {
int res, pmk_len;
pmk_len = PMK_LEN;
res = eapol_sm_get_key(wpa_s->eapol, sm->pmk, PMK_LEN);
@@ -927,7 +979,7 @@ static int wpa_supplicant_get_pmk(struct wpa_supplicant *wpa_s,
}
}
- if (abort_cached && wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
+ if (abort_cached && sm->key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
/* Send EAPOL-Start to trigger full EAP authentication. */
wpa_printf(MSG_DEBUG, "RSN: no PMKSA entry found - trigger "
"full EAP authentication");
@@ -978,11 +1030,11 @@ static int wpa_supplicant_send_2_of_4(struct wpa_supplicant *wpa_s,
if (rbuf == NULL)
return -1;
- reply->type = wpa_s->proto == WPA_PROTO_RSN ?
+ reply->type = sm->proto == WPA_PROTO_RSN ?
EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
WPA_PUT_BE16(reply->key_info,
ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC);
- if (wpa_s->proto == WPA_PROTO_RSN)
+ if (sm->proto == WPA_PROTO_RSN)
WPA_PUT_BE16(reply->key_length, 0);
else
memcpy(reply->key_length, key->key_length, 2);
@@ -1044,7 +1096,7 @@ static void wpa_supplicant_process_1_of_4(struct wpa_supplicant *wpa_s,
memset(&ie, 0, sizeof(ie));
- if (wpa_s->proto == WPA_PROTO_RSN) {
+ if (sm->proto == WPA_PROTO_RSN) {
/* RSN: msg 1/4 should contain PMKID for the selected PMK */
const u8 *buf = (const u8 *) (key + 1);
size_t len = WPA_GET_BE16(key->key_data_length);
@@ -1080,8 +1132,8 @@ static void wpa_supplicant_key_neg_complete(struct wpa_supplicant *wpa_s,
wpa_msg(wpa_s, MSG_INFO, "WPA: Key negotiation completed with "
MACSTR " [PTK=%s GTK=%s]", MAC2STR(addr),
- wpa_cipher_txt(wpa_s->pairwise_cipher),
- wpa_cipher_txt(wpa_s->group_cipher));
+ wpa_cipher_txt(sm->pairwise_cipher),
+ wpa_cipher_txt(sm->group_cipher));
eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
wpa_supplicant_cancel_auth_timeout(wpa_s);
wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
@@ -1089,7 +1141,7 @@ static void wpa_supplicant_key_neg_complete(struct wpa_supplicant *wpa_s,
if (secure) {
/* MLME.SETPROTECTION.request(TA, Tx_Rx) */
eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
- if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK)
+ if (sm->key_mgmt == WPA_KEY_MGMT_PSK)
eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
/*
* Start preauthentication after a short wait to avoid a
@@ -1120,7 +1172,7 @@ static int wpa_supplicant_install_ptk(struct wpa_supplicant *wpa_s,
wpa_printf(MSG_DEBUG, "WPA: Installing PTK to the driver.");
- switch (wpa_s->pairwise_cipher) {
+ switch (sm->pairwise_cipher) {
case WPA_CIPHER_CCMP:
alg = WPA_ALG_CCMP;
keylen = 16;
@@ -1137,11 +1189,11 @@ static int wpa_supplicant_install_ptk(struct wpa_supplicant *wpa_s,
return 0;
default:
wpa_printf(MSG_WARNING, "WPA: Unsupported pairwise cipher %d",
- wpa_s->pairwise_cipher);
+ sm->pairwise_cipher);
return -1;
}
- if (wpa_s->proto == WPA_PROTO_RSN) {
+ if (sm->proto == WPA_PROTO_RSN) {
key_rsc = null_rsc;
} else {
key_rsc = key->key_rsc;
@@ -1227,12 +1279,13 @@ static int wpa_supplicant_install_gtk(struct wpa_supplicant *wpa_s,
{
const u8 *_gtk = gd->gtk;
u8 gtk_buf[32];
+ struct wpa_sm *sm = wpa_s->wpa;
wpa_hexdump_key(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len);
wpa_printf(MSG_DEBUG, "WPA: Installing GTK to the driver "
"(keyidx=%d tx=%d).", gd->keyidx, gd->tx);
wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, gd->key_rsc_len);
- if (wpa_s->group_cipher == WPA_CIPHER_TKIP) {
+ if (sm->group_cipher == WPA_CIPHER_TKIP) {
/* Swap Tx/Rx keys for Michael MIC */
memcpy(gtk_buf, gd->gtk, 16);
memcpy(gtk_buf + 16, gd->gtk + 24, 8);
@@ -1240,7 +1293,7 @@ static int wpa_supplicant_install_gtk(struct wpa_supplicant *wpa_s,
_gtk = gtk_buf;
}
wpa_s->keys_cleared = 0;
- if (wpa_s->pairwise_cipher == WPA_CIPHER_NONE) {
+ if (sm->pairwise_cipher == WPA_CIPHER_NONE) {
if (wpa_drv_set_key(wpa_s, gd->alg,
(u8 *) "\xff\xff\xff\xff\xff\xff",
gd->keyidx, 1, key_rsc, gd->key_rsc_len,
@@ -1262,10 +1315,10 @@ static int wpa_supplicant_install_gtk(struct wpa_supplicant *wpa_s,
}
-static int wpa_supplicant_gtk_tx_bit_workaround(
- const struct wpa_supplicant *wpa_s, int tx)
+static int wpa_supplicant_gtk_tx_bit_workaround(const struct wpa_sm *sm,
+ int tx)
{
- if (tx && wpa_s->pairwise_cipher != WPA_CIPHER_NONE) {
+ if (tx && sm->pairwise_cipher != WPA_CIPHER_NONE) {
/* Ignore Tx bit for GTK if a pairwise key is used. One AP
* seemed to set this bit (incorrectly, since Tx is only when
* doing Group Key only APs) and without this workaround, the
@@ -1286,6 +1339,7 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_supplicant *wpa_s,
int key_info)
{
struct wpa_gtk_data gd;
+ struct wpa_sm *sm = wpa_s->wpa;
/*
* IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames - Figure 43x
@@ -1303,7 +1357,7 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_supplicant *wpa_s,
return -1;
gd.keyidx = gtk[0] & 0x3;
- gd.tx = wpa_supplicant_gtk_tx_bit_workaround(wpa_s,
+ gd.tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
!!(gtk[0] & BIT(2)));
gtk += 2;
gtk_len -= 2;
@@ -1311,7 +1365,7 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_supplicant *wpa_s,
memcpy(gd.gtk, gtk, gtk_len);
gd.gtk_len = gtk_len;
- if (wpa_supplicant_check_group_cipher(wpa_s->group_cipher,
+ if (wpa_supplicant_check_group_cipher(sm->group_cipher,
gtk_len, gtk_len,
&gd.key_rsc_len, &gd.alg) ||
wpa_supplicant_install_gtk(wpa_s, &gd, key->key_rsc)) {
@@ -1369,6 +1423,7 @@ static int wpa_supplicant_validate_ie(struct wpa_supplicant *wpa_s,
struct wpa_eapol_ie_parse *ie)
{
struct wpa_ssid *ssid = wpa_s->wpa->cur_ssid;
+ struct wpa_sm *sm = wpa_s->wpa;
if (wpa_s->ap_wpa_ie == NULL && wpa_s->ap_rsn_ie == NULL) {
wpa_printf(MSG_DEBUG, "WPA: No WPA/RSN IE for this AP known. "
@@ -1395,7 +1450,7 @@ static int wpa_supplicant_validate_ie(struct wpa_supplicant *wpa_s,
return -1;
}
- if (wpa_s->proto == WPA_PROTO_WPA &&
+ if (sm->proto == WPA_PROTO_WPA &&
ie->rsn_ie && wpa_s->ap_rsn_ie == NULL &&
ssid && (ssid->proto & WPA_PROTO_RSN)) {
wpa_report_ie_mismatch(wpa_s, "Possible downgrade attack "
@@ -1427,12 +1482,12 @@ static int wpa_supplicant_send_4_of_4(struct wpa_supplicant *wpa_s,
if (rbuf == NULL)
return -1;
- reply->type = wpa_s->proto == WPA_PROTO_RSN ?
+ reply->type = sm->proto == WPA_PROTO_RSN ?
EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
key_info &= WPA_KEY_INFO_SECURE;
key_info |= ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC;
WPA_PUT_BE16(reply->key_info, key_info);
- if (wpa_s->proto == WPA_PROTO_RSN)
+ if (sm->proto == WPA_PROTO_RSN)
WPA_PUT_BE16(reply->key_length, 0);
else
memcpy(reply->key_length, key->key_length, 2);
@@ -1485,7 +1540,7 @@ static void wpa_supplicant_process_3_of_4(struct wpa_supplicant *wpa_s,
}
keylen = WPA_GET_BE16(key->key_length);
- switch (wpa_s->pairwise_cipher) {
+ switch (sm->pairwise_cipher) {
case WPA_CIPHER_CCMP:
if (keylen != 16) {
wpa_printf(MSG_WARNING, "WPA: Invalid CCMP key length "
@@ -1530,7 +1585,7 @@ static void wpa_supplicant_process_3_of_4(struct wpa_supplicant *wpa_s,
}
-static int wpa_supplicant_process_1_of_2_rsn(struct wpa_supplicant *wpa_s,
+static int wpa_supplicant_process_1_of_2_rsn(struct wpa_sm *sm,
const u8 *keydata,
size_t keydatalen,
int key_info,
@@ -1551,7 +1606,7 @@ static int wpa_supplicant_process_1_of_2_rsn(struct wpa_supplicant *wpa_s,
}
maxkeylen = gd->gtk_len = ie.gtk_len - 2;
- if (wpa_supplicant_check_group_cipher(wpa_s->group_cipher,
+ if (wpa_supplicant_check_group_cipher(sm->group_cipher,
gd->gtk_len, maxkeylen,
&gd->key_rsc_len, &gd->alg))
return -1;
@@ -1559,7 +1614,7 @@ static int wpa_supplicant_process_1_of_2_rsn(struct wpa_supplicant *wpa_s,
wpa_hexdump(MSG_DEBUG, "RSN: received GTK in group key handshake",
ie.gtk, ie.gtk_len);
gd->keyidx = ie.gtk[0] & 0x3;
- gd->tx = wpa_supplicant_gtk_tx_bit_workaround(wpa_s,
+ gd->tx = wpa_supplicant_gtk_tx_bit_workaround(sm,
!!(ie.gtk[0] & BIT(2)));
if (ie.gtk_len - 2 > sizeof(gd->gtk)) {
wpa_printf(MSG_INFO, "RSN: Too long GTK in GTK IE "
@@ -1572,13 +1627,12 @@ static int wpa_supplicant_process_1_of_2_rsn(struct wpa_supplicant *wpa_s,
}
-static int wpa_supplicant_process_1_of_2_wpa(struct wpa_supplicant *wpa_s,
+static int wpa_supplicant_process_1_of_2_wpa(struct wpa_sm *sm,
const struct wpa_eapol_key *key,
size_t keydatalen, int key_info,
int extra_len, u16 ver,
struct wpa_gtk_data *gd)
{
- struct wpa_sm *sm = wpa_s->wpa;
int maxkeylen;
u8 ek[32];
@@ -1593,7 +1647,7 @@ static int wpa_supplicant_process_1_of_2_wpa(struct wpa_supplicant *wpa_s,
if (ver == WPA_KEY_INFO_TYPE_HMAC_SHA1_AES)
maxkeylen -= 8;
- if (wpa_supplicant_check_group_cipher(wpa_s->group_cipher,
+ if (wpa_supplicant_check_group_cipher(sm->group_cipher,
gd->gtk_len, maxkeylen,
&gd->key_rsc_len, &gd->alg))
return -1;
@@ -1625,7 +1679,7 @@ static int wpa_supplicant_process_1_of_2_wpa(struct wpa_supplicant *wpa_s,
}
}
gd->tx = wpa_supplicant_gtk_tx_bit_workaround(
- wpa_s, !!(key_info & WPA_KEY_INFO_TXRX));
+ sm, !!(key_info & WPA_KEY_INFO_TXRX));
return 0;
}
@@ -1646,12 +1700,12 @@ static int wpa_supplicant_send_2_of_2(struct wpa_supplicant *wpa_s,
if (rbuf == NULL)
return -1;
- reply->type = wpa_s->proto == WPA_PROTO_RSN ?
+ reply->type = sm->proto == WPA_PROTO_RSN ?
EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
key_info &= WPA_KEY_INFO_KEY_INDEX_MASK;
key_info |= ver | WPA_KEY_INFO_MIC | WPA_KEY_INFO_SECURE;
WPA_PUT_BE16(reply->key_info, key_info);
- if (wpa_s->proto == WPA_PROTO_RSN)
+ if (sm->proto == WPA_PROTO_RSN)
WPA_PUT_BE16(reply->key_length, 0);
else
memcpy(reply->key_length, key->key_length, 2);
@@ -1676,6 +1730,7 @@ static void wpa_supplicant_process_1_of_2(struct wpa_supplicant *wpa_s,
u16 key_info, keydatalen;
int rekey;
struct wpa_gtk_data gd;
+ struct wpa_sm *sm = wpa_s->wpa;
memset(&gd, 0, sizeof(gd));
@@ -1687,14 +1742,14 @@ static void wpa_supplicant_process_1_of_2(struct wpa_supplicant *wpa_s,
key_info = WPA_GET_BE16(key->key_info);
keydatalen = WPA_GET_BE16(key->key_data_length);
- if (wpa_s->proto == WPA_PROTO_RSN) {
- if (wpa_supplicant_process_1_of_2_rsn(wpa_s,
+ if (sm->proto == WPA_PROTO_RSN) {
+ if (wpa_supplicant_process_1_of_2_rsn(sm,
(const u8 *) (key + 1),
keydatalen, key_info,
&gd))
return;
} else {
- if (wpa_supplicant_process_1_of_2_wpa(wpa_s, key, keydatalen,
+ if (wpa_supplicant_process_1_of_2_wpa(sm, key, keydatalen,
key_info, extra_len,
ver, &gd))
return;
@@ -1707,7 +1762,7 @@ static void wpa_supplicant_process_1_of_2(struct wpa_supplicant *wpa_s,
if (rekey) {
wpa_msg(wpa_s, MSG_INFO, "WPA: Group rekeying completed with "
MACSTR " [GTK=%s]", MAC2STR(src_addr),
- wpa_cipher_txt(wpa_s->group_cipher));
+ wpa_cipher_txt(sm->group_cipher));
wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
} else {
wpa_supplicant_key_neg_complete(wpa_s, src_addr,
@@ -1902,11 +1957,11 @@ int wpa_sm_rx_eapol(struct wpa_supplicant *wpa_s, unsigned char *src_addr,
return -1;
}
- if (wpa_s->pairwise_cipher == WPA_CIPHER_CCMP &&
+ if (sm->pairwise_cipher == WPA_CIPHER_CCMP &&
ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES) {
wpa_printf(MSG_INFO, "WPA: CCMP is used, but EAPOL-Key "
"descriptor version (%d) is not 2.", ver);
- if (wpa_s->group_cipher != WPA_CIPHER_CCMP &&
+ if (sm->group_cipher != WPA_CIPHER_CCMP &&
!(key_info & WPA_KEY_INFO_KEY_TYPE)) {
/* Earlier versions of IEEE 802.11i did not explicitly
* require version 2 descriptor for all EAPOL-Key
@@ -1952,7 +2007,7 @@ int wpa_sm_rx_eapol(struct wpa_supplicant *wpa_s, unsigned char *src_addr,
return -1;
}
- if (wpa_s->proto == WPA_PROTO_RSN &&
+ if (sm->proto == WPA_PROTO_RSN &&
(key_info & WPA_KEY_INFO_ENCR_KEY_DATA) &&
wpa_supplicant_decrypt_key_data(sm, key, ver))
return -1;
@@ -2004,16 +2059,16 @@ static int wpa_cipher_bits(int cipher)
}
-static const u8 * wpa_key_mgmt_suite(struct wpa_supplicant *wpa_s)
+static const u8 * wpa_key_mgmt_suite(struct wpa_sm *sm)
{
static const u8 *dummy = (u8 *) "\x00\x00\x00\x00";
- switch (wpa_s->key_mgmt) {
+ switch (sm->key_mgmt) {
case WPA_KEY_MGMT_IEEE8021X:
- return (wpa_s->proto == WPA_PROTO_RSN ?
+ return (sm->proto == WPA_PROTO_RSN ?
RSN_AUTH_KEY_MGMT_UNSPEC_802_1X :
WPA_AUTH_KEY_MGMT_UNSPEC_802_1X);
case WPA_KEY_MGMT_PSK:
- return (wpa_s->proto == WPA_PROTO_RSN ?
+ return (sm->proto == WPA_PROTO_RSN ?
RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X :
WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X);
case WPA_KEY_MGMT_WPA_NONE:
@@ -2024,24 +2079,24 @@ static const u8 * wpa_key_mgmt_suite(struct wpa_supplicant *wpa_s)
}
-static const u8 * wpa_cipher_suite(struct wpa_supplicant *wpa_s, int cipher)
+static const u8 * wpa_cipher_suite(struct wpa_sm *sm, int cipher)
{
static const u8 *dummy = (u8 *) "\x00\x00\x00\x00";
switch (cipher) {
case WPA_CIPHER_CCMP:
- return (wpa_s->proto == WPA_PROTO_RSN ?
+ return (sm->proto == WPA_PROTO_RSN ?
RSN_CIPHER_SUITE_CCMP : WPA_CIPHER_SUITE_CCMP);
case WPA_CIPHER_TKIP:
- return (wpa_s->proto == WPA_PROTO_RSN ?
+ return (sm->proto == WPA_PROTO_RSN ?
RSN_CIPHER_SUITE_TKIP : WPA_CIPHER_SUITE_TKIP);
case WPA_CIPHER_WEP104:
- return (wpa_s->proto == WPA_PROTO_RSN ?
+ return (sm->proto == WPA_PROTO_RSN ?
RSN_CIPHER_SUITE_WEP104 : WPA_CIPHER_SUITE_WEP104);
case WPA_CIPHER_WEP40:
- return (wpa_s->proto == WPA_PROTO_RSN ?
+ return (sm->proto == WPA_PROTO_RSN ?
RSN_CIPHER_SUITE_WEP40 : WPA_CIPHER_SUITE_WEP40);
case WPA_CIPHER_NONE:
- return (wpa_s->proto == WPA_PROTO_RSN ?
+ return (sm->proto == WPA_PROTO_RSN ?
RSN_CIPHER_SUITE_NONE : WPA_CIPHER_SUITE_NONE);
default:
return dummy;
@@ -2076,9 +2131,9 @@ int wpa_get_mib(struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
} else
pmkid_txt[0] = '\0';
- if ((wpa_s->key_mgmt == WPA_KEY_MGMT_PSK ||
- wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X) &&
- wpa_s->proto == WPA_PROTO_RSN)
+ if ((sm->key_mgmt == WPA_KEY_MGMT_PSK ||
+ sm->key_mgmt == WPA_KEY_MGMT_IEEE8021X) &&
+ sm->proto == WPA_PROTO_RSN)
rsna = 1;
else
rsna = 0;
@@ -2107,21 +2162,19 @@ int wpa_get_mib(struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
rsna ? "TRUE" : "FALSE",
rsna ? "TRUE" : "FALSE",
RSN_VERSION,
- wpa_cipher_bits(wpa_s->group_cipher),
+ wpa_cipher_bits(sm->group_cipher),
sm->dot11RSNAConfigPMKLifetime,
sm->dot11RSNAConfigPMKReauthThreshold,
sm->dot11RSNAConfigSATimeout,
- RSN_SUITE_ARG(wpa_key_mgmt_suite(wpa_s)),
- RSN_SUITE_ARG(wpa_cipher_suite(wpa_s,
- wpa_s->pairwise_cipher)),
- RSN_SUITE_ARG(wpa_cipher_suite(wpa_s,
- wpa_s->group_cipher)),
+ RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),
+ RSN_SUITE_ARG(wpa_cipher_suite(sm,
+ sm->pairwise_cipher)),
+ RSN_SUITE_ARG(wpa_cipher_suite(sm, sm->group_cipher)),
pmkid_txt,
- RSN_SUITE_ARG(wpa_key_mgmt_suite(wpa_s)),
- RSN_SUITE_ARG(wpa_cipher_suite(wpa_s,
- wpa_s->pairwise_cipher)),
- RSN_SUITE_ARG(wpa_cipher_suite(wpa_s,
- wpa_s->group_cipher)),
+ RSN_SUITE_ARG(wpa_key_mgmt_suite(sm)),
+ RSN_SUITE_ARG(wpa_cipher_suite(sm,
+ sm->pairwise_cipher)),
+ RSN_SUITE_ARG(wpa_cipher_suite(sm, sm->group_cipher)),
wpa_s->dot11RSNA4WayHandshakeFailures);
return len;
}
@@ -2309,13 +2362,13 @@ void wpa_sm_set_ifname(struct wpa_sm *sm, const char *ifname)
/**
- * wpa_sm_configure - Configure WPA state machine parameters
+ * wpa_sm_set_param - Set WPA state machine parameters
* @sm: Pointer to WPA state machine data from wpa_sm_init()
* @param: Parameter field
* @value: Parameter value
* Returns: 0 on success, -1 on failure
*/
-int wpa_sm_configure(struct wpa_sm *sm, enum wpa_sm_conf_params param,
+int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
unsigned int value)
{
int ret = 0;
@@ -2342,7 +2395,79 @@ int wpa_sm_configure(struct wpa_sm *sm, enum wpa_sm_conf_params param,
else
ret = -1;
break;
+ case WPA_PARAM_PROTO:
+ sm->proto = value;
+ break;
+ case WPA_PARAM_PAIRWISE:
+ sm->pairwise_cipher = value;
+ break;
+ case WPA_PARAM_GROUP:
+ sm->group_cipher = value;
+ break;
+ case WPA_PARAM_KEY_MGMT:
+ sm->key_mgmt = value;
+ break;
}
return ret;
}
+
+
+/**
+ * wpa_sm_get_param - Get WPA state machine parameters
+ * @sm: Pointer to WPA state machine data from wpa_sm_init()
+ * @param: Parameter field
+ * Returns: Parameter value
+ */
+unsigned int wpa_sm_get_param(struct wpa_sm *sm, enum wpa_sm_conf_params param)
+{
+ if (sm == NULL)
+ return 0;
+
+ switch (param) {
+ case RSNA_PMK_LIFETIME:
+ return sm->dot11RSNAConfigPMKLifetime;
+ case RSNA_PMK_REAUTH_THRESHOLD:
+ return sm->dot11RSNAConfigPMKReauthThreshold;
+ case RSNA_SA_TIMEOUT:
+ return sm->dot11RSNAConfigSATimeout;
+ case WPA_PARAM_PROTO:
+ return sm->proto;
+ case WPA_PARAM_PAIRWISE:
+ return sm->pairwise_cipher;
+ case WPA_PARAM_GROUP:
+ return sm->group_cipher;
+ case WPA_PARAM_KEY_MGMT:
+ return sm->key_mgmt;
+ default:
+ return 0;
+ }
+}
+
+
+/**
+ * wpa_sm_get_status - Get WPA state machine
+ * @sm: Pointer to WPA state machine data from wpa_sm_init()
+ * @buf: Buffer for status information
+ * @buflen: Maximum buffer length
+ * @verbose: Whether to include verbose status information
+ * Returns: Number of bytes written to buf.
+ *
+ * Query WPA state machine for status information. This function fills in
+ * a text area with current status information. If the buffer (buf) is not
+ * large enough, status information will be truncated to fit the buffer.
+ */
+int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
+ int verbose)
+{
+ char *pos = buf, *end = buf + buflen;
+
+ pos += snprintf(pos, end - pos,
+ "pairwise_cipher=%s\n"
+ "group_cipher=%s\n"
+ "key_mgmt=%s\n",
+ wpa_cipher_txt(sm->pairwise_cipher),
+ wpa_cipher_txt(sm->group_cipher),
+ wpa_key_mgmt_txt(sm->key_mgmt, sm->proto));
+ return pos - buf;
+}
diff --git a/wpa_supplicant/wpa.h b/wpa_supplicant/wpa.h
index 23be366..67a93d1 100644
--- a/wpa_supplicant/wpa.h
+++ b/wpa_supplicant/wpa.h
@@ -146,11 +146,21 @@ void wpa_sm_set_ifname(struct wpa_sm *sm, const char *ifname);
enum wpa_sm_conf_params {
RSNA_PMK_LIFETIME /* dot11RSNAConfigPMKLifetime */,
RSNA_PMK_REAUTH_THRESHOLD /* dot11RSNAConfigPMKReauthThreshold */,
- RSNA_SA_TIMEOUT /* dot11RSNAConfigSATimeout */
+ RSNA_SA_TIMEOUT /* dot11RSNAConfigSATimeout */,
+ WPA_PARAM_PROTO,
+ WPA_PARAM_PAIRWISE,
+ WPA_PARAM_GROUP,
+ WPA_PARAM_KEY_MGMT
};
-int wpa_sm_configure(struct wpa_sm *sm, enum wpa_sm_conf_params param,
+int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
unsigned int value);
+unsigned int wpa_sm_get_param(struct wpa_sm *sm,
+ enum wpa_sm_conf_params param);
+
+int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
+ int verbose);
+
struct wpa_supplicant;
diff --git a/wpa_supplicant/wpa_i.h b/wpa_supplicant/wpa_i.h
index 4f1eccb..903cf20 100644
--- a/wpa_supplicant/wpa_i.h
+++ b/wpa_supplicant/wpa_i.h
@@ -85,6 +85,12 @@ struct wpa_sm {
unsigned int dot11RSNAConfigPMKLifetime;
unsigned int dot11RSNAConfigPMKReauthThreshold;
unsigned int dot11RSNAConfigSATimeout;
+
+ /* Selected configuration (based on Beacon/ProbeResp WPA IE) */
+ unsigned int proto;
+ unsigned int pairwise_cipher;
+ unsigned int group_cipher;
+ unsigned int key_mgmt;
};
#endif /* WPA_I_H */
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 30d1bc6..90479f0 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -546,6 +546,11 @@ void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
}
}
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
+ wpa_s->pairwise_cipher);
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
+
pmksa_cache_clear_current(wpa_s->wpa);
}
@@ -938,7 +943,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
"pairwise %d key_mgmt %d",
ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt);
- wpa_s->proto = proto;
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
free(wpa_s->ap_wpa_ie);
wpa_s->ap_wpa_ie = NULL;
@@ -1016,6 +1021,11 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
return -1;
}
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
+ wpa_s->pairwise_cipher);
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
+
*wpa_ie_len = wpa_gen_wpa_ie(wpa_s, wpa_ie, *wpa_ie_len);
if (*wpa_ie_len < 0) {
wpa_printf(MSG_WARNING, "WPA: Failed to generate WPA IE.");
@@ -1740,7 +1750,7 @@ static int wpa_supplicant_init2(struct wpa_supplicant *wpa_s,
wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
- wpa_sm_configure(wpa_s->wpa, RSNA_PMK_LIFETIME,
+ wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
fprintf(stderr, "Invalid WPA parameter value for "
"dot11RSNAConfigPMKLifetime\n");
@@ -1748,7 +1758,7 @@ static int wpa_supplicant_init2(struct wpa_supplicant *wpa_s,
}
if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
- wpa_sm_configure(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
+ wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
fprintf(stderr, "Invalid WPA parameter value for "
"dot11RSNAConfigPMKReauthThreshold\n");
@@ -1756,7 +1766,7 @@ static int wpa_supplicant_init2(struct wpa_supplicant *wpa_s,
}
if (wpa_s->conf->dot11RSNAConfigSATimeout &&
- wpa_sm_configure(wpa_s->wpa, RSNA_SA_TIMEOUT,
+ wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
wpa_s->conf->dot11RSNAConfigSATimeout)) {
fprintf(stderr, "Invalid WPA parameter value for "
"dot11RSNAConfigSATimeout\n");
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 8335e63..7608f7c 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -64,7 +64,6 @@ struct wpa_supplicant {
size_t assoc_wpa_ie_len;
/* Selected configuration (based on Beacon/ProbeResp WPA IE) */
- int proto;
int pairwise_cipher;
int group_cipher;
int key_mgmt;