Add Suite B 192-bit AKM
WPA-EAP-SUITE-B-192 can now be used to select 192-bit level Suite B into use as the key management method. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
97ae35a848
commit
5e3b5197cc
26 changed files with 397 additions and 106 deletions
|
@ -215,6 +215,11 @@ NEED_SHA256=y
|
||||||
NEED_AES_OMAC1=y
|
NEED_AES_OMAC1=y
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_SUITEB192
|
||||||
|
L_CFLAGS += -DCONFIG_SUITEB192
|
||||||
|
NEED_SHA384=y
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef CONFIG_IEEE80211W
|
ifdef CONFIG_IEEE80211W
|
||||||
L_CFLAGS += -DCONFIG_IEEE80211W
|
L_CFLAGS += -DCONFIG_IEEE80211W
|
||||||
NEED_SHA256=y
|
NEED_SHA256=y
|
||||||
|
|
|
@ -204,6 +204,11 @@ NEED_SHA256=y
|
||||||
NEED_AES_OMAC1=y
|
NEED_AES_OMAC1=y
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_SUITEB192
|
||||||
|
CFLAGS += -DCONFIG_SUITEB192
|
||||||
|
NEED_SHA384=y
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef CONFIG_IEEE80211W
|
ifdef CONFIG_IEEE80211W
|
||||||
CFLAGS += -DCONFIG_IEEE80211W
|
CFLAGS += -DCONFIG_IEEE80211W
|
||||||
NEED_SHA256=y
|
NEED_SHA256=y
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* hostapd / Configuration file parser
|
* hostapd / Configuration file parser
|
||||||
* Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -680,8 +680,14 @@ static int hostapd_config_parse_key_mgmt(int line, const char *value)
|
||||||
else if (os_strcmp(start, "FT-SAE") == 0)
|
else if (os_strcmp(start, "FT-SAE") == 0)
|
||||||
val |= WPA_KEY_MGMT_FT_SAE;
|
val |= WPA_KEY_MGMT_FT_SAE;
|
||||||
#endif /* CONFIG_SAE */
|
#endif /* CONFIG_SAE */
|
||||||
|
#ifdef CONFIG_SUITEB
|
||||||
else if (os_strcmp(start, "WPA-EAP-SUITE-B") == 0)
|
else if (os_strcmp(start, "WPA-EAP-SUITE-B") == 0)
|
||||||
val |= WPA_KEY_MGMT_IEEE8021X_SUITE_B;
|
val |= WPA_KEY_MGMT_IEEE8021X_SUITE_B;
|
||||||
|
#endif /* CONFIG_SUITEB */
|
||||||
|
#ifdef CONFIG_SUITEB192
|
||||||
|
else if (os_strcmp(start, "WPA-EAP-SUITE-B-192") == 0)
|
||||||
|
val |= WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
|
||||||
|
#endif /* CONFIG_SUITEB192 */
|
||||||
else {
|
else {
|
||||||
wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
|
wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
|
||||||
line, start);
|
line, start);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* hostapd / UNIX domain socket -based control interface
|
* hostapd / UNIX domain socket -based control interface
|
||||||
* Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -1171,6 +1171,14 @@ static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
|
||||||
return pos - buf;
|
return pos - buf;
|
||||||
pos += ret;
|
pos += ret;
|
||||||
}
|
}
|
||||||
|
if (hapd->conf->wpa_key_mgmt &
|
||||||
|
WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
|
||||||
|
ret = os_snprintf(pos, end - pos,
|
||||||
|
"WPA-EAP-SUITE-B-192 ");
|
||||||
|
if (os_snprintf_error(end - pos, ret))
|
||||||
|
return pos - buf;
|
||||||
|
pos += ret;
|
||||||
|
}
|
||||||
|
|
||||||
ret = os_snprintf(pos, end - pos, "\n");
|
ret = os_snprintf(pos, end - pos, "\n");
|
||||||
if (os_snprintf_error(end - pos, ret))
|
if (os_snprintf_error(end - pos, ret))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* hostapd - PMKSA cache for IEEE 802.11i RSN
|
* hostapd - PMKSA cache for IEEE 802.11i RSN
|
||||||
* Copyright (c) 2004-2008, 2012, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2004-2008, 2012-2015, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -269,7 +269,9 @@ pmksa_cache_auth_add(struct rsn_pmksa_cache *pmksa,
|
||||||
return NULL;
|
return NULL;
|
||||||
os_memcpy(entry->pmk, pmk, pmk_len);
|
os_memcpy(entry->pmk, pmk, pmk_len);
|
||||||
entry->pmk_len = pmk_len;
|
entry->pmk_len = pmk_len;
|
||||||
if (wpa_key_mgmt_suite_b(akmp))
|
if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
|
||||||
|
rsn_pmkid_suite_b_192(kck, kck_len, aa, spa, entry->pmkid);
|
||||||
|
else if (wpa_key_mgmt_suite_b(akmp))
|
||||||
rsn_pmkid_suite_b(kck, kck_len, aa, spa, entry->pmkid);
|
rsn_pmkid_suite_b(kck, kck_len, aa, spa, entry->pmkid);
|
||||||
else
|
else
|
||||||
rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid,
|
rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid,
|
||||||
|
|
|
@ -849,34 +849,45 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
|
||||||
{
|
{
|
||||||
struct ieee802_1x_hdr *hdr;
|
struct ieee802_1x_hdr *hdr;
|
||||||
struct wpa_eapol_key *key;
|
struct wpa_eapol_key *key;
|
||||||
|
struct wpa_eapol_key_192 *key192;
|
||||||
u16 key_info, key_data_length;
|
u16 key_info, key_data_length;
|
||||||
enum { PAIRWISE_2, PAIRWISE_4, GROUP_2, REQUEST,
|
enum { PAIRWISE_2, PAIRWISE_4, GROUP_2, REQUEST,
|
||||||
SMK_M1, SMK_M3, SMK_ERROR } msg;
|
SMK_M1, SMK_M3, SMK_ERROR } msg;
|
||||||
char *msgtxt;
|
char *msgtxt;
|
||||||
struct wpa_eapol_ie_parse kde;
|
struct wpa_eapol_ie_parse kde;
|
||||||
int ft;
|
int ft;
|
||||||
const u8 *eapol_key_ie;
|
const u8 *eapol_key_ie, *key_data;
|
||||||
size_t eapol_key_ie_len;
|
size_t eapol_key_ie_len, keyhdrlen, mic_len;
|
||||||
|
|
||||||
if (wpa_auth == NULL || !wpa_auth->conf.wpa || sm == NULL)
|
if (wpa_auth == NULL || !wpa_auth->conf.wpa || sm == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (data_len < sizeof(*hdr) + sizeof(*key))
|
mic_len = wpa_mic_len(sm->wpa_key_mgmt);
|
||||||
|
keyhdrlen = mic_len == 24 ? sizeof(*key192) : sizeof(*key);
|
||||||
|
|
||||||
|
if (data_len < sizeof(*hdr) + keyhdrlen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hdr = (struct ieee802_1x_hdr *) data;
|
hdr = (struct ieee802_1x_hdr *) data;
|
||||||
key = (struct wpa_eapol_key *) (hdr + 1);
|
key = (struct wpa_eapol_key *) (hdr + 1);
|
||||||
|
key192 = (struct wpa_eapol_key_192 *) (hdr + 1);
|
||||||
key_info = WPA_GET_BE16(key->key_info);
|
key_info = WPA_GET_BE16(key->key_info);
|
||||||
|
if (mic_len == 24) {
|
||||||
|
key_data = (const u8 *) (key192 + 1);
|
||||||
|
key_data_length = WPA_GET_BE16(key192->key_data_length);
|
||||||
|
} else {
|
||||||
|
key_data = (const u8 *) (key + 1);
|
||||||
key_data_length = WPA_GET_BE16(key->key_data_length);
|
key_data_length = WPA_GET_BE16(key->key_data_length);
|
||||||
|
}
|
||||||
wpa_printf(MSG_DEBUG, "WPA: Received EAPOL-Key from " MACSTR
|
wpa_printf(MSG_DEBUG, "WPA: Received EAPOL-Key from " MACSTR
|
||||||
" key_info=0x%x type=%u key_data_length=%u",
|
" key_info=0x%x type=%u key_data_length=%u",
|
||||||
MAC2STR(sm->addr), key_info, key->type, key_data_length);
|
MAC2STR(sm->addr), key_info, key->type, key_data_length);
|
||||||
if (key_data_length > data_len - sizeof(*hdr) - sizeof(*key)) {
|
if (key_data_length > data_len - sizeof(*hdr) - keyhdrlen) {
|
||||||
wpa_printf(MSG_INFO, "WPA: Invalid EAPOL-Key frame - "
|
wpa_printf(MSG_INFO, "WPA: Invalid EAPOL-Key frame - "
|
||||||
"key_data overflow (%d > %lu)",
|
"key_data overflow (%d > %lu)",
|
||||||
key_data_length,
|
key_data_length,
|
||||||
(unsigned long) (data_len - sizeof(*hdr) -
|
(unsigned long) (data_len - sizeof(*hdr) -
|
||||||
sizeof(*key)));
|
keyhdrlen));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1083,8 +1094,7 @@ continue_processing:
|
||||||
wpa_sta_disconnect(wpa_auth, sm->addr);
|
wpa_sta_disconnect(wpa_auth, sm->addr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (wpa_parse_kde_ies((u8 *) (key + 1), key_data_length,
|
if (wpa_parse_kde_ies(key_data, key_data_length, &kde) < 0) {
|
||||||
&kde) < 0) {
|
|
||||||
wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
|
wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
|
||||||
"received EAPOL-Key msg 2/4 with "
|
"received EAPOL-Key msg 2/4 with "
|
||||||
"invalid Key Data contents");
|
"invalid Key Data contents");
|
||||||
|
@ -1241,8 +1251,7 @@ continue_processing:
|
||||||
*/
|
*/
|
||||||
if (msg == SMK_ERROR) {
|
if (msg == SMK_ERROR) {
|
||||||
#ifdef CONFIG_PEERKEY
|
#ifdef CONFIG_PEERKEY
|
||||||
wpa_smk_error(wpa_auth, sm, (const u8 *) (key + 1),
|
wpa_smk_error(wpa_auth, sm, key_data, key_data_length);
|
||||||
key_data_length);
|
|
||||||
#endif /* CONFIG_PEERKEY */
|
#endif /* CONFIG_PEERKEY */
|
||||||
return;
|
return;
|
||||||
} else if (key_info & WPA_KEY_INFO_ERROR) {
|
} else if (key_info & WPA_KEY_INFO_ERROR) {
|
||||||
|
@ -1257,12 +1266,12 @@ continue_processing:
|
||||||
wpa_request_new_ptk(sm);
|
wpa_request_new_ptk(sm);
|
||||||
#ifdef CONFIG_PEERKEY
|
#ifdef CONFIG_PEERKEY
|
||||||
} else if (msg == SMK_M1) {
|
} else if (msg == SMK_M1) {
|
||||||
wpa_smk_m1(wpa_auth, sm, key, (const u8 *) (key + 1),
|
wpa_smk_m1(wpa_auth, sm, key, key_data,
|
||||||
key_data_length);
|
key_data_length);
|
||||||
#endif /* CONFIG_PEERKEY */
|
#endif /* CONFIG_PEERKEY */
|
||||||
} else if (key_data_length > 0 &&
|
} else if (key_data_length > 0 &&
|
||||||
wpa_parse_kde_ies((const u8 *) (key + 1),
|
wpa_parse_kde_ies(key_data, key_data_length,
|
||||||
key_data_length, &kde) == 0 &&
|
&kde) == 0 &&
|
||||||
kde.mac_addr) {
|
kde.mac_addr) {
|
||||||
} else {
|
} else {
|
||||||
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
|
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
|
||||||
|
@ -1300,8 +1309,7 @@ continue_processing:
|
||||||
|
|
||||||
#ifdef CONFIG_PEERKEY
|
#ifdef CONFIG_PEERKEY
|
||||||
if (msg == SMK_M3) {
|
if (msg == SMK_M3) {
|
||||||
wpa_smk_m3(wpa_auth, sm, key, (const u8 *) (key + 1),
|
wpa_smk_m3(wpa_auth, sm, key, key_data, key_data_length);
|
||||||
key_data_length);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_PEERKEY */
|
#endif /* CONFIG_PEERKEY */
|
||||||
|
@ -1376,14 +1384,19 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
|
||||||
{
|
{
|
||||||
struct ieee802_1x_hdr *hdr;
|
struct ieee802_1x_hdr *hdr;
|
||||||
struct wpa_eapol_key *key;
|
struct wpa_eapol_key *key;
|
||||||
size_t len;
|
struct wpa_eapol_key_192 *key192;
|
||||||
|
size_t len, mic_len, keyhdrlen;
|
||||||
int alg;
|
int alg;
|
||||||
int key_data_len, pad_len = 0;
|
int key_data_len, pad_len = 0;
|
||||||
u8 *buf, *pos;
|
u8 *buf, *pos;
|
||||||
int version, pairwise;
|
int version, pairwise;
|
||||||
int i;
|
int i;
|
||||||
|
u8 *key_data;
|
||||||
|
|
||||||
len = sizeof(struct ieee802_1x_hdr) + sizeof(struct wpa_eapol_key);
|
mic_len = wpa_mic_len(sm->wpa_key_mgmt);
|
||||||
|
keyhdrlen = mic_len == 24 ? sizeof(*key192) : sizeof(*key);
|
||||||
|
|
||||||
|
len = sizeof(struct ieee802_1x_hdr) + keyhdrlen;
|
||||||
|
|
||||||
if (force_version)
|
if (force_version)
|
||||||
version = force_version;
|
version = force_version;
|
||||||
|
@ -1430,6 +1443,8 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
|
||||||
hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
|
hdr->type = IEEE802_1X_TYPE_EAPOL_KEY;
|
||||||
hdr->length = host_to_be16(len - sizeof(*hdr));
|
hdr->length = host_to_be16(len - sizeof(*hdr));
|
||||||
key = (struct wpa_eapol_key *) (hdr + 1);
|
key = (struct wpa_eapol_key *) (hdr + 1);
|
||||||
|
key192 = (struct wpa_eapol_key_192 *) (hdr + 1);
|
||||||
|
key_data = ((u8 *) (hdr + 1)) + keyhdrlen;
|
||||||
|
|
||||||
key->type = sm->wpa == WPA_VERSION_WPA2 ?
|
key->type = sm->wpa == WPA_VERSION_WPA2 ?
|
||||||
EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
|
EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;
|
||||||
|
@ -1466,7 +1481,10 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
|
||||||
os_memcpy(key->key_rsc, key_rsc, WPA_KEY_RSC_LEN);
|
os_memcpy(key->key_rsc, key_rsc, WPA_KEY_RSC_LEN);
|
||||||
|
|
||||||
if (kde && !encr) {
|
if (kde && !encr) {
|
||||||
os_memcpy(key + 1, kde, kde_len);
|
os_memcpy(key_data, kde, kde_len);
|
||||||
|
if (mic_len == 24)
|
||||||
|
WPA_PUT_BE16(key192->key_data_length, kde_len);
|
||||||
|
else
|
||||||
WPA_PUT_BE16(key->key_data_length, kde_len);
|
WPA_PUT_BE16(key->key_data_length, kde_len);
|
||||||
} else if (encr && kde) {
|
} else if (encr && kde) {
|
||||||
buf = os_zalloc(key_data_len);
|
buf = os_zalloc(key_data_len);
|
||||||
|
@ -1488,13 +1506,17 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
|
||||||
wpa_key_mgmt_suite_b(sm->wpa_key_mgmt) ||
|
wpa_key_mgmt_suite_b(sm->wpa_key_mgmt) ||
|
||||||
version == WPA_KEY_INFO_TYPE_AES_128_CMAC) {
|
version == WPA_KEY_INFO_TYPE_AES_128_CMAC) {
|
||||||
if (aes_wrap(sm->PTK.kek, sm->PTK.kek_len,
|
if (aes_wrap(sm->PTK.kek, sm->PTK.kek_len,
|
||||||
(key_data_len - 8) / 8, buf,
|
(key_data_len - 8) / 8, buf, key_data)) {
|
||||||
(u8 *) (key + 1))) {
|
|
||||||
os_free(hdr);
|
os_free(hdr);
|
||||||
os_free(buf);
|
os_free(buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
WPA_PUT_BE16(key->key_data_length, key_data_len);
|
if (mic_len == 24)
|
||||||
|
WPA_PUT_BE16(key192->key_data_length,
|
||||||
|
key_data_len);
|
||||||
|
else
|
||||||
|
WPA_PUT_BE16(key->key_data_length,
|
||||||
|
key_data_len);
|
||||||
} else if (sm->PTK.kek_len == 16) {
|
} else if (sm->PTK.kek_len == 16) {
|
||||||
u8 ek[32];
|
u8 ek[32];
|
||||||
os_memcpy(key->key_iv,
|
os_memcpy(key->key_iv,
|
||||||
|
@ -1502,9 +1524,14 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
|
||||||
inc_byte_array(sm->group->Counter, WPA_NONCE_LEN);
|
inc_byte_array(sm->group->Counter, WPA_NONCE_LEN);
|
||||||
os_memcpy(ek, key->key_iv, 16);
|
os_memcpy(ek, key->key_iv, 16);
|
||||||
os_memcpy(ek + 16, sm->PTK.kek, sm->PTK.kek_len);
|
os_memcpy(ek + 16, sm->PTK.kek, sm->PTK.kek_len);
|
||||||
os_memcpy(key + 1, buf, key_data_len);
|
os_memcpy(key_data, buf, key_data_len);
|
||||||
rc4_skip(ek, 32, 256, (u8 *) (key + 1), key_data_len);
|
rc4_skip(ek, 32, 256, key_data, key_data_len);
|
||||||
WPA_PUT_BE16(key->key_data_length, key_data_len);
|
if (mic_len == 24)
|
||||||
|
WPA_PUT_BE16(key192->key_data_length,
|
||||||
|
key_data_len);
|
||||||
|
else
|
||||||
|
WPA_PUT_BE16(key->key_data_length,
|
||||||
|
key_data_len);
|
||||||
} else {
|
} else {
|
||||||
os_free(hdr);
|
os_free(hdr);
|
||||||
os_free(buf);
|
os_free(buf);
|
||||||
|
@ -1514,6 +1541,8 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key_info & WPA_KEY_INFO_MIC) {
|
if (key_info & WPA_KEY_INFO_MIC) {
|
||||||
|
u8 *key_mic;
|
||||||
|
|
||||||
if (!sm->PTK_valid) {
|
if (!sm->PTK_valid) {
|
||||||
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
|
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
|
||||||
"PTK not valid when sending EAPOL-Key "
|
"PTK not valid when sending EAPOL-Key "
|
||||||
|
@ -1521,9 +1550,11 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
|
||||||
os_free(hdr);
|
os_free(hdr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key_mic = key192->key_mic; /* same offset for key and key192 */
|
||||||
wpa_eapol_key_mic(sm->PTK.kck, sm->PTK.kck_len,
|
wpa_eapol_key_mic(sm->PTK.kck, sm->PTK.kck_len,
|
||||||
sm->wpa_key_mgmt, version,
|
sm->wpa_key_mgmt, version,
|
||||||
(u8 *) hdr, len, key->key_mic);
|
(u8 *) hdr, len, key_mic);
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
if (!pairwise &&
|
if (!pairwise &&
|
||||||
wpa_auth->conf.corrupt_gtk_rekey_mic_probability > 0.0 &&
|
wpa_auth->conf.corrupt_gtk_rekey_mic_probability > 0.0 &&
|
||||||
|
@ -1531,7 +1562,7 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
|
||||||
wpa_auth->conf.corrupt_gtk_rekey_mic_probability) {
|
wpa_auth->conf.corrupt_gtk_rekey_mic_probability) {
|
||||||
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
|
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
|
||||||
"Corrupting group EAPOL-Key Key MIC");
|
"Corrupting group EAPOL-Key Key MIC");
|
||||||
key->key_mic[0]++;
|
key_mic[0]++;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
}
|
}
|
||||||
|
@ -1580,25 +1611,27 @@ static int wpa_verify_key_mic(int akmp, struct wpa_ptk *PTK, u8 *data,
|
||||||
{
|
{
|
||||||
struct ieee802_1x_hdr *hdr;
|
struct ieee802_1x_hdr *hdr;
|
||||||
struct wpa_eapol_key *key;
|
struct wpa_eapol_key *key;
|
||||||
|
struct wpa_eapol_key_192 *key192;
|
||||||
u16 key_info;
|
u16 key_info;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
|
u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
|
||||||
size_t mic_len = 16;
|
size_t mic_len = wpa_mic_len(akmp);
|
||||||
|
|
||||||
if (data_len < sizeof(*hdr) + sizeof(*key))
|
if (data_len < sizeof(*hdr) + sizeof(*key))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
hdr = (struct ieee802_1x_hdr *) data;
|
hdr = (struct ieee802_1x_hdr *) data;
|
||||||
key = (struct wpa_eapol_key *) (hdr + 1);
|
key = (struct wpa_eapol_key *) (hdr + 1);
|
||||||
|
key192 = (struct wpa_eapol_key_192 *) (hdr + 1);
|
||||||
key_info = WPA_GET_BE16(key->key_info);
|
key_info = WPA_GET_BE16(key->key_info);
|
||||||
os_memcpy(mic, key->key_mic, mic_len);
|
os_memcpy(mic, key192->key_mic, mic_len);
|
||||||
os_memset(key->key_mic, 0, mic_len);
|
os_memset(key192->key_mic, 0, mic_len);
|
||||||
if (wpa_eapol_key_mic(PTK->kck, PTK->kck_len, akmp,
|
if (wpa_eapol_key_mic(PTK->kck, PTK->kck_len, akmp,
|
||||||
key_info & WPA_KEY_INFO_TYPE_MASK,
|
key_info & WPA_KEY_INFO_TYPE_MASK,
|
||||||
data, data_len, key->key_mic) ||
|
data, data_len, key192->key_mic) ||
|
||||||
os_memcmp_const(mic, key->key_mic, mic_len) != 0)
|
os_memcmp_const(mic, key192->key_mic, mic_len) != 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
os_memcpy(key->key_mic, mic, mic_len);
|
os_memcpy(key192->key_mic, mic, mic_len);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* hostapd - WPA/RSN IE and KDE definitions
|
* hostapd - WPA/RSN IE and KDE definitions
|
||||||
* Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -205,6 +205,11 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
|
||||||
pos += RSN_SELECTOR_LEN;
|
pos += RSN_SELECTOR_LEN;
|
||||||
num_suites++;
|
num_suites++;
|
||||||
}
|
}
|
||||||
|
if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
|
||||||
|
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192);
|
||||||
|
pos += RSN_SELECTOR_LEN;
|
||||||
|
num_suites++;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_RSN_TESTING
|
#ifdef CONFIG_RSN_TESTING
|
||||||
if (rsn_testing) {
|
if (rsn_testing) {
|
||||||
|
@ -482,6 +487,8 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
|
||||||
selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
|
selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
|
||||||
if (0) {
|
if (0) {
|
||||||
}
|
}
|
||||||
|
else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
|
||||||
|
selector = RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192;
|
||||||
else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
|
else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
|
||||||
selector = RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
|
selector = RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
|
||||||
#ifdef CONFIG_IEEE80211R
|
#ifdef CONFIG_IEEE80211R
|
||||||
|
@ -562,6 +569,8 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
|
||||||
}
|
}
|
||||||
if (0) {
|
if (0) {
|
||||||
}
|
}
|
||||||
|
else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
|
||||||
|
sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
|
||||||
else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
|
else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
|
||||||
sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B;
|
sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B;
|
||||||
#ifdef CONFIG_IEEE80211R
|
#ifdef CONFIG_IEEE80211R
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* WPA Supplicant - Common definitions
|
* WPA Supplicant - Common definitions
|
||||||
* Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -50,6 +50,7 @@ typedef enum { FALSE = 0, TRUE = 1 } Boolean;
|
||||||
#define WPA_KEY_MGMT_CCKM BIT(14)
|
#define WPA_KEY_MGMT_CCKM BIT(14)
|
||||||
#define WPA_KEY_MGMT_OSEN BIT(15)
|
#define WPA_KEY_MGMT_OSEN BIT(15)
|
||||||
#define WPA_KEY_MGMT_IEEE8021X_SUITE_B BIT(16)
|
#define WPA_KEY_MGMT_IEEE8021X_SUITE_B BIT(16)
|
||||||
|
#define WPA_KEY_MGMT_IEEE8021X_SUITE_B_192 BIT(17)
|
||||||
|
|
||||||
static inline int wpa_key_mgmt_wpa_ieee8021x(int akm)
|
static inline int wpa_key_mgmt_wpa_ieee8021x(int akm)
|
||||||
{
|
{
|
||||||
|
@ -58,7 +59,8 @@ static inline int wpa_key_mgmt_wpa_ieee8021x(int akm)
|
||||||
WPA_KEY_MGMT_CCKM |
|
WPA_KEY_MGMT_CCKM |
|
||||||
WPA_KEY_MGMT_OSEN |
|
WPA_KEY_MGMT_OSEN |
|
||||||
WPA_KEY_MGMT_IEEE8021X_SHA256 |
|
WPA_KEY_MGMT_IEEE8021X_SHA256 |
|
||||||
WPA_KEY_MGMT_IEEE8021X_SUITE_B));
|
WPA_KEY_MGMT_IEEE8021X_SUITE_B |
|
||||||
|
WPA_KEY_MGMT_IEEE8021X_SUITE_B_192));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int wpa_key_mgmt_wpa_psk(int akm)
|
static inline int wpa_key_mgmt_wpa_psk(int akm)
|
||||||
|
@ -91,9 +93,15 @@ static inline int wpa_key_mgmt_sha256(int akm)
|
||||||
WPA_KEY_MGMT_IEEE8021X_SUITE_B));
|
WPA_KEY_MGMT_IEEE8021X_SUITE_B));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int wpa_key_mgmt_sha384(int akm)
|
||||||
|
{
|
||||||
|
return !!(akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192);
|
||||||
|
}
|
||||||
|
|
||||||
static inline int wpa_key_mgmt_suite_b(int akm)
|
static inline int wpa_key_mgmt_suite_b(int akm)
|
||||||
{
|
{
|
||||||
return !!(akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B);
|
return !!(akm & (WPA_KEY_MGMT_IEEE8021X_SUITE_B |
|
||||||
|
WPA_KEY_MGMT_IEEE8021X_SUITE_B_192));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int wpa_key_mgmt_wpa(int akm)
|
static inline int wpa_key_mgmt_wpa(int akm)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* IEEE 802.11 Frame type definitions
|
* IEEE 802.11 Frame type definitions
|
||||||
* Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2002-2015, Jouni Malinen <j@w1.fi>
|
||||||
* Copyright (c) 2007-2008 Intel Corporation
|
* Copyright (c) 2007-2008 Intel Corporation
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
|
@ -1192,6 +1192,7 @@ enum plink_action_field {
|
||||||
#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
|
#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
|
||||||
#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
|
#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
|
||||||
#define WLAN_AKM_SUITE_8021X_SUITE_B 0x000FAC11
|
#define WLAN_AKM_SUITE_8021X_SUITE_B 0x000FAC11
|
||||||
|
#define WLAN_AKM_SUITE_8021X_SUITE_B_192 0x000FAC12
|
||||||
#define WLAN_AKM_SUITE_CCKM 0x00409600
|
#define WLAN_AKM_SUITE_CCKM 0x00409600
|
||||||
#define WLAN_AKM_SUITE_OSEN 0x506f9a01
|
#define WLAN_AKM_SUITE_OSEN 0x506f9a01
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "crypto/md5.h"
|
#include "crypto/md5.h"
|
||||||
#include "crypto/sha1.h"
|
#include "crypto/sha1.h"
|
||||||
#include "crypto/sha256.h"
|
#include "crypto/sha256.h"
|
||||||
|
#include "crypto/sha384.h"
|
||||||
#include "crypto/aes_wrap.h"
|
#include "crypto/aes_wrap.h"
|
||||||
#include "crypto/crypto.h"
|
#include "crypto/crypto.h"
|
||||||
#include "ieee802_11_defs.h"
|
#include "ieee802_11_defs.h"
|
||||||
|
@ -21,12 +22,24 @@
|
||||||
|
|
||||||
static unsigned int wpa_kck_len(int akmp)
|
static unsigned int wpa_kck_len(int akmp)
|
||||||
{
|
{
|
||||||
|
if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
|
||||||
|
return 24;
|
||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static unsigned int wpa_kek_len(int akmp)
|
static unsigned int wpa_kek_len(int akmp)
|
||||||
{
|
{
|
||||||
|
if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
|
||||||
|
return 32;
|
||||||
|
return 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int wpa_mic_len(int akmp)
|
||||||
|
{
|
||||||
|
if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
|
||||||
|
return 24;
|
||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +67,7 @@ static unsigned int wpa_kek_len(int akmp)
|
||||||
int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
|
int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
|
||||||
const u8 *buf, size_t len, u8 *mic)
|
const u8 *buf, size_t len, u8 *mic)
|
||||||
{
|
{
|
||||||
u8 hash[SHA256_MAC_LEN];
|
u8 hash[SHA384_MAC_LEN];
|
||||||
|
|
||||||
switch (ver) {
|
switch (ver) {
|
||||||
#ifndef CONFIG_FIPS
|
#ifndef CONFIG_FIPS
|
||||||
|
@ -83,6 +96,13 @@ int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
|
||||||
os_memcpy(mic, hash, MD5_MAC_LEN);
|
os_memcpy(mic, hash, MD5_MAC_LEN);
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_SUITEB */
|
#endif /* CONFIG_SUITEB */
|
||||||
|
#ifdef CONFIG_SUITEB192
|
||||||
|
case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
|
||||||
|
if (hmac_sha384(key, key_len, buf, len, hash))
|
||||||
|
return -1;
|
||||||
|
os_memcpy(mic, hash, 24);
|
||||||
|
break;
|
||||||
|
#endif /* CONFIG_SUITEB192 */
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -452,6 +472,8 @@ static int rsn_key_mgmt_to_bitfield(const u8 *s)
|
||||||
#endif /* CONFIG_SAE */
|
#endif /* CONFIG_SAE */
|
||||||
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B)
|
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B)
|
||||||
return WPA_KEY_MGMT_IEEE8021X_SUITE_B;
|
return WPA_KEY_MGMT_IEEE8021X_SUITE_B;
|
||||||
|
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192)
|
||||||
|
return WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1034,6 +1056,39 @@ int rsn_pmkid_suite_b(const u8 *kck, size_t kck_len, const u8 *aa,
|
||||||
#endif /* CONFIG_SUITEB */
|
#endif /* CONFIG_SUITEB */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_SUITEB192
|
||||||
|
/**
|
||||||
|
* rsn_pmkid_suite_b_192 - Calculate PMK identifier for Suite B AKM
|
||||||
|
* @kck: Key confirmation key
|
||||||
|
* @kck_len: Length of kck in bytes
|
||||||
|
* @aa: Authenticator address
|
||||||
|
* @spa: Supplicant address
|
||||||
|
* @pmkid: Buffer for PMKID
|
||||||
|
* Returns: 0 on success, -1 on failure
|
||||||
|
*
|
||||||
|
* IEEE Std 802.11ac-2013 - 11.6.1.3 Pairwise key hierarchy
|
||||||
|
* PMKID = Truncate(HMAC-SHA-384(KCK, "PMK Name" || AA || SPA))
|
||||||
|
*/
|
||||||
|
int rsn_pmkid_suite_b_192(const u8 *kck, size_t kck_len, const u8 *aa,
|
||||||
|
const u8 *spa, u8 *pmkid)
|
||||||
|
{
|
||||||
|
char *title = "PMK Name";
|
||||||
|
const u8 *addr[3];
|
||||||
|
const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
|
||||||
|
unsigned char hash[SHA384_MAC_LEN];
|
||||||
|
|
||||||
|
addr[0] = (u8 *) title;
|
||||||
|
addr[1] = aa;
|
||||||
|
addr[2] = spa;
|
||||||
|
|
||||||
|
if (hmac_sha384_vector(kck, kck_len, 3, addr, len, hash) < 0)
|
||||||
|
return -1;
|
||||||
|
os_memcpy(pmkid, hash, PMKID_LEN);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_SUITEB192 */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wpa_cipher_txt - Convert cipher suite to a text string
|
* wpa_cipher_txt - Convert cipher suite to a text string
|
||||||
* @cipher: Cipher suite (WPA_CIPHER_* enum)
|
* @cipher: Cipher suite (WPA_CIPHER_* enum)
|
||||||
|
@ -1113,6 +1168,8 @@ const char * wpa_key_mgmt_txt(int key_mgmt, int proto)
|
||||||
return "OSEN";
|
return "OSEN";
|
||||||
case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
|
case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
|
||||||
return "WPA2-EAP-SUITE-B";
|
return "WPA2-EAP-SUITE-B";
|
||||||
|
case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
|
||||||
|
return "WPA2-EAP-SUITE-B-192";
|
||||||
default:
|
default:
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
}
|
}
|
||||||
|
@ -1141,6 +1198,8 @@ u32 wpa_akm_to_suite(int akm)
|
||||||
return WLAN_AKM_SUITE_OSEN;
|
return WLAN_AKM_SUITE_OSEN;
|
||||||
if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
|
if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
|
||||||
return WLAN_AKM_SUITE_8021X_SUITE_B;
|
return WLAN_AKM_SUITE_8021X_SUITE_B;
|
||||||
|
if (akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
|
||||||
|
return WLAN_AKM_SUITE_8021X_SUITE_B_192;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,8 +63,8 @@ WPA_CIPHER_GTK_NOT_USED)
|
||||||
#define RSN_AUTH_KEY_MGMT_SAE RSN_SELECTOR(0x00, 0x0f, 0xac, 8)
|
#define RSN_AUTH_KEY_MGMT_SAE RSN_SELECTOR(0x00, 0x0f, 0xac, 8)
|
||||||
#define RSN_AUTH_KEY_MGMT_FT_SAE RSN_SELECTOR(0x00, 0x0f, 0xac, 9)
|
#define RSN_AUTH_KEY_MGMT_FT_SAE RSN_SELECTOR(0x00, 0x0f, 0xac, 9)
|
||||||
#define RSN_AUTH_KEY_MGMT_802_1X_SUITE_B RSN_SELECTOR(0x00, 0x0f, 0xac, 11)
|
#define RSN_AUTH_KEY_MGMT_802_1X_SUITE_B RSN_SELECTOR(0x00, 0x0f, 0xac, 11)
|
||||||
#define RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_384 RSN_SELECTOR(0x00, 0x0f, 0xac, 12)
|
#define RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192 RSN_SELECTOR(0x00, 0x0f, 0xac, 12)
|
||||||
#define RSN_AUTH_KEY_MGMT_FT_802_1X_SUITE_B_384 \
|
#define RSN_AUTH_KEY_MGMT_FT_802_1X_SUITE_B_192 \
|
||||||
RSN_SELECTOR(0x00, 0x0f, 0xac, 13)
|
RSN_SELECTOR(0x00, 0x0f, 0xac, 13)
|
||||||
#define RSN_AUTH_KEY_MGMT_CCKM RSN_SELECTOR(0x00, 0x40, 0x96, 0x00)
|
#define RSN_AUTH_KEY_MGMT_CCKM RSN_SELECTOR(0x00, 0x40, 0x96, 0x00)
|
||||||
#define RSN_AUTH_KEY_MGMT_OSEN RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x01)
|
#define RSN_AUTH_KEY_MGMT_OSEN RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x01)
|
||||||
|
@ -191,9 +191,24 @@ struct wpa_eapol_key {
|
||||||
/* followed by key_data_length bytes of key_data */
|
/* followed by key_data_length bytes of key_data */
|
||||||
} STRUCT_PACKED;
|
} STRUCT_PACKED;
|
||||||
|
|
||||||
#define WPA_EAPOL_KEY_MIC_MAX_LEN 16
|
struct wpa_eapol_key_192 {
|
||||||
#define WPA_KCK_MAX_LEN 16
|
u8 type;
|
||||||
#define WPA_KEK_MAX_LEN 16
|
/* Note: key_info, key_length, and key_data_length are unaligned */
|
||||||
|
u8 key_info[2]; /* big endian */
|
||||||
|
u8 key_length[2]; /* big endian */
|
||||||
|
u8 replay_counter[WPA_REPLAY_COUNTER_LEN];
|
||||||
|
u8 key_nonce[WPA_NONCE_LEN];
|
||||||
|
u8 key_iv[16];
|
||||||
|
u8 key_rsc[WPA_KEY_RSC_LEN];
|
||||||
|
u8 key_id[8]; /* Reserved in IEEE 802.11i/RSN */
|
||||||
|
u8 key_mic[24];
|
||||||
|
u8 key_data_length[2]; /* big endian */
|
||||||
|
/* followed by key_data_length bytes of key_data */
|
||||||
|
} STRUCT_PACKED;
|
||||||
|
|
||||||
|
#define WPA_EAPOL_KEY_MIC_MAX_LEN 24
|
||||||
|
#define WPA_KCK_MAX_LEN 24
|
||||||
|
#define WPA_KEK_MAX_LEN 32
|
||||||
#define WPA_TK_MAX_LEN 32
|
#define WPA_TK_MAX_LEN 32
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -386,6 +401,16 @@ static inline int rsn_pmkid_suite_b(const u8 *kck, size_t kck_len, const u8 *aa,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_SUITEB */
|
#endif /* CONFIG_SUITEB */
|
||||||
|
#ifdef CONFIG_SUITEB192
|
||||||
|
int rsn_pmkid_suite_b_192(const u8 *kck, size_t kck_len, const u8 *aa,
|
||||||
|
const u8 *spa, u8 *pmkid);
|
||||||
|
#else /* CONFIG_SUITEB192 */
|
||||||
|
static inline int rsn_pmkid_suite_b_192(const u8 *kck, size_t kck_len,
|
||||||
|
const u8 *aa, const u8 *spa, u8 *pmkid)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_SUITEB192 */
|
||||||
|
|
||||||
const char * wpa_cipher_txt(int cipher);
|
const char * wpa_cipher_txt(int cipher);
|
||||||
const char * wpa_key_mgmt_txt(int key_mgmt, int proto);
|
const char * wpa_key_mgmt_txt(int key_mgmt, int proto);
|
||||||
|
@ -431,5 +456,6 @@ int wpa_pick_group_cipher(int ciphers);
|
||||||
int wpa_parse_cipher(const char *value);
|
int wpa_parse_cipher(const char *value);
|
||||||
int wpa_write_ciphers(char *start, char *end, int ciphers, const char *delim);
|
int wpa_write_ciphers(char *start, char *end, int ciphers, const char *delim);
|
||||||
int wpa_select_ap_group_cipher(int wpa, int wpa_pairwise, int rsn_pairwise);
|
int wpa_select_ap_group_cipher(int wpa, int wpa_pairwise, int rsn_pairwise);
|
||||||
|
unsigned int wpa_mic_len(int akmp);
|
||||||
|
|
||||||
#endif /* WPA_COMMON_H */
|
#endif /* WPA_COMMON_H */
|
||||||
|
|
|
@ -4463,7 +4463,8 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
|
||||||
params->key_mgmt_suite == WPA_KEY_MGMT_OSEN ||
|
params->key_mgmt_suite == WPA_KEY_MGMT_OSEN ||
|
||||||
params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
|
params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
|
||||||
params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
|
params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
|
||||||
params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
|
params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B ||
|
||||||
|
params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
|
||||||
int mgmt = WLAN_AKM_SUITE_PSK;
|
int mgmt = WLAN_AKM_SUITE_PSK;
|
||||||
|
|
||||||
switch (params->key_mgmt_suite) {
|
switch (params->key_mgmt_suite) {
|
||||||
|
@ -4491,6 +4492,9 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
|
||||||
case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
|
case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
|
||||||
mgmt = WLAN_AKM_SUITE_8021X_SUITE_B;
|
mgmt = WLAN_AKM_SUITE_8021X_SUITE_B;
|
||||||
break;
|
break;
|
||||||
|
case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
|
||||||
|
mgmt = WLAN_AKM_SUITE_8021X_SUITE_B_192;
|
||||||
|
break;
|
||||||
case WPA_KEY_MGMT_PSK:
|
case WPA_KEY_MGMT_PSK:
|
||||||
default:
|
default:
|
||||||
mgmt = WLAN_AKM_SUITE_PSK;
|
mgmt = WLAN_AKM_SUITE_PSK;
|
||||||
|
|
|
@ -65,6 +65,7 @@ static int wpa_supplicant_send_smk_error(struct wpa_sm *sm, const u8 *dst,
|
||||||
{
|
{
|
||||||
size_t rlen;
|
size_t rlen;
|
||||||
struct wpa_eapol_key *err;
|
struct wpa_eapol_key *err;
|
||||||
|
struct wpa_eapol_key_192 *err192;
|
||||||
struct rsn_error_kde error;
|
struct rsn_error_kde error;
|
||||||
u8 *rbuf, *pos;
|
u8 *rbuf, *pos;
|
||||||
size_t kde_len;
|
size_t kde_len;
|
||||||
|
@ -79,6 +80,7 @@ static int wpa_supplicant_send_smk_error(struct wpa_sm *sm, const u8 *dst,
|
||||||
(void *) &err);
|
(void *) &err);
|
||||||
if (rbuf == NULL)
|
if (rbuf == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
err192 = (struct wpa_eapol_key_192 *) err;
|
||||||
|
|
||||||
err->type = EAPOL_KEY_TYPE_RSN;
|
err->type = EAPOL_KEY_TYPE_RSN;
|
||||||
key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
|
key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
|
||||||
|
@ -113,7 +115,7 @@ static int wpa_supplicant_send_smk_error(struct wpa_sm *sm, const u8 *dst,
|
||||||
}
|
}
|
||||||
|
|
||||||
wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver, dst,
|
wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver, dst,
|
||||||
ETH_P_EAPOL, rbuf, rlen, err->key_mic);
|
ETH_P_EAPOL, rbuf, rlen, err192->key_mic);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -126,6 +128,7 @@ static int wpa_supplicant_send_smk_m3(struct wpa_sm *sm,
|
||||||
{
|
{
|
||||||
size_t rlen;
|
size_t rlen;
|
||||||
struct wpa_eapol_key *reply;
|
struct wpa_eapol_key *reply;
|
||||||
|
struct wpa_eapol_key_192 *reply192;
|
||||||
u8 *rbuf, *pos;
|
u8 *rbuf, *pos;
|
||||||
size_t kde_len;
|
size_t kde_len;
|
||||||
u16 key_info;
|
u16 key_info;
|
||||||
|
@ -140,6 +143,7 @@ static int wpa_supplicant_send_smk_m3(struct wpa_sm *sm,
|
||||||
(void *) &reply);
|
(void *) &reply);
|
||||||
if (rbuf == NULL)
|
if (rbuf == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
reply192 = (struct wpa_eapol_key_192 *) reply;
|
||||||
|
|
||||||
reply->type = EAPOL_KEY_TYPE_RSN;
|
reply->type = EAPOL_KEY_TYPE_RSN;
|
||||||
key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
|
key_info = ver | WPA_KEY_INFO_SMK_MESSAGE | WPA_KEY_INFO_MIC |
|
||||||
|
@ -165,7 +169,7 @@ static int wpa_supplicant_send_smk_m3(struct wpa_sm *sm,
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK M3");
|
wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK M3");
|
||||||
wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver, src_addr,
|
wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver, src_addr,
|
||||||
ETH_P_EAPOL, rbuf, rlen, reply->key_mic);
|
ETH_P_EAPOL, rbuf, rlen, reply192->key_mic);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -907,7 +911,7 @@ static void wpa_supplicant_process_stk_4_of_4(struct wpa_sm *sm,
|
||||||
*/
|
*/
|
||||||
int peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
|
int peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
|
||||||
struct wpa_peerkey *peerkey,
|
struct wpa_peerkey *peerkey,
|
||||||
struct wpa_eapol_key *key, u16 ver,
|
struct wpa_eapol_key_192 *key, u16 ver,
|
||||||
const u8 *buf, size_t len)
|
const u8 *buf, size_t len)
|
||||||
{
|
{
|
||||||
u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
|
u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
|
||||||
|
|
|
@ -38,7 +38,7 @@ struct wpa_peerkey {
|
||||||
|
|
||||||
int peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
|
int peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
|
||||||
struct wpa_peerkey *peerkey,
|
struct wpa_peerkey *peerkey,
|
||||||
struct wpa_eapol_key *key, u16 ver,
|
struct wpa_eapol_key_192 *key, u16 ver,
|
||||||
const u8 *buf, size_t len);
|
const u8 *buf, size_t len);
|
||||||
void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey,
|
void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey,
|
||||||
struct wpa_eapol_key *key, u16 key_info, u16 ver,
|
struct wpa_eapol_key *key, u16 key_info, u16 ver,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* WPA Supplicant - RSN PMKSA cache
|
* WPA Supplicant - RSN PMKSA cache
|
||||||
* Copyright (c) 2004-2009, 2011-2012, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2004-2009, 2011-2015, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -141,7 +141,9 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
|
||||||
return NULL;
|
return NULL;
|
||||||
os_memcpy(entry->pmk, pmk, pmk_len);
|
os_memcpy(entry->pmk, pmk, pmk_len);
|
||||||
entry->pmk_len = pmk_len;
|
entry->pmk_len = pmk_len;
|
||||||
if (wpa_key_mgmt_suite_b(akmp))
|
if (akmp == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
|
||||||
|
rsn_pmkid_suite_b_192(kck, kck_len, aa, spa, entry->pmkid);
|
||||||
|
else if (wpa_key_mgmt_suite_b(akmp))
|
||||||
rsn_pmkid_suite_b(kck, kck_len, aa, spa, entry->pmkid);
|
rsn_pmkid_suite_b(kck, kck_len, aa, spa, entry->pmkid);
|
||||||
else
|
else
|
||||||
rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid,
|
rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* RSN pre-authentication (supplicant)
|
* RSN pre-authentication (supplicant)
|
||||||
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -300,7 +300,8 @@ void rsn_preauth_candidate_process(struct wpa_sm *sm)
|
||||||
wpa_sm_get_state(sm) != WPA_COMPLETED ||
|
wpa_sm_get_state(sm) != WPA_COMPLETED ||
|
||||||
(sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X &&
|
(sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X &&
|
||||||
sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X_SHA256 &&
|
sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X_SHA256 &&
|
||||||
sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X_SUITE_B)) {
|
sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X_SUITE_B &&
|
||||||
|
sm->key_mgmt != WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)) {
|
||||||
wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: not in suitable "
|
wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: not in suitable "
|
||||||
"state for new pre-authentication");
|
"state for new pre-authentication");
|
||||||
return; /* invalid state for new pre-auth */
|
return; /* invalid state for new pre-auth */
|
||||||
|
|
|
@ -39,7 +39,7 @@ void wpa_eapol_key_send(struct wpa_sm *sm, const u8 *kck, size_t kck_len,
|
||||||
int ver, const u8 *dest, u16 proto,
|
int ver, const u8 *dest, u16 proto,
|
||||||
u8 *msg, size_t msg_len, u8 *key_mic)
|
u8 *msg, size_t msg_len, u8 *key_mic)
|
||||||
{
|
{
|
||||||
size_t mic_len = 16;
|
size_t mic_len = wpa_mic_len(sm->key_mgmt);
|
||||||
|
|
||||||
if (is_zero_ether_addr(dest) && is_zero_ether_addr(sm->bssid)) {
|
if (is_zero_ether_addr(dest) && is_zero_ether_addr(sm->bssid)) {
|
||||||
/*
|
/*
|
||||||
|
@ -88,10 +88,11 @@ out:
|
||||||
*/
|
*/
|
||||||
void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise)
|
void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise)
|
||||||
{
|
{
|
||||||
size_t rlen;
|
size_t mic_len, hdrlen, rlen;
|
||||||
struct wpa_eapol_key *reply;
|
struct wpa_eapol_key *reply;
|
||||||
|
struct wpa_eapol_key_192 *reply192;
|
||||||
int key_info, ver;
|
int key_info, ver;
|
||||||
u8 bssid[ETH_ALEN], *rbuf;
|
u8 bssid[ETH_ALEN], *rbuf, *key_mic;
|
||||||
|
|
||||||
if (sm->key_mgmt == WPA_KEY_MGMT_OSEN ||
|
if (sm->key_mgmt == WPA_KEY_MGMT_OSEN ||
|
||||||
wpa_key_mgmt_suite_b(sm->key_mgmt))
|
wpa_key_mgmt_suite_b(sm->key_mgmt))
|
||||||
|
@ -110,10 +111,13 @@ void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mic_len = wpa_mic_len(sm->key_mgmt);
|
||||||
|
hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply);
|
||||||
rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
|
rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
|
||||||
sizeof(*reply), &rlen, (void *) &reply);
|
hdrlen, &rlen, (void *) &reply);
|
||||||
if (rbuf == NULL)
|
if (rbuf == NULL)
|
||||||
return;
|
return;
|
||||||
|
reply192 = (struct wpa_eapol_key_192 *) reply;
|
||||||
|
|
||||||
reply->type = (sm->proto == WPA_PROTO_RSN ||
|
reply->type = (sm->proto == WPA_PROTO_RSN ||
|
||||||
sm->proto == WPA_PROTO_OSEN) ?
|
sm->proto == WPA_PROTO_OSEN) ?
|
||||||
|
@ -131,15 +135,21 @@ void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise)
|
||||||
WPA_REPLAY_COUNTER_LEN);
|
WPA_REPLAY_COUNTER_LEN);
|
||||||
inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
|
inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
|
||||||
|
|
||||||
|
if (mic_len == 24)
|
||||||
|
WPA_PUT_BE16(reply192->key_data_length, 0);
|
||||||
|
else
|
||||||
WPA_PUT_BE16(reply->key_data_length, 0);
|
WPA_PUT_BE16(reply->key_data_length, 0);
|
||||||
|
if (!(key_info & WPA_KEY_INFO_MIC))
|
||||||
|
key_mic = NULL;
|
||||||
|
else
|
||||||
|
key_mic = reply192->key_mic; /* same offset in reply */
|
||||||
|
|
||||||
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
|
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
|
||||||
"WPA: Sending EAPOL-Key Request (error=%d "
|
"WPA: Sending EAPOL-Key Request (error=%d "
|
||||||
"pairwise=%d ptk_set=%d len=%lu)",
|
"pairwise=%d ptk_set=%d len=%lu)",
|
||||||
error, pairwise, sm->ptk_set, (unsigned long) rlen);
|
error, pairwise, sm->ptk_set, (unsigned long) rlen);
|
||||||
wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver, bssid,
|
wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver, bssid,
|
||||||
ETH_P_EAPOL, rbuf, rlen,
|
ETH_P_EAPOL, rbuf, rlen, key_mic);
|
||||||
key_info & WPA_KEY_INFO_MIC ? reply->key_mic : NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -305,9 +315,10 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
|
||||||
const u8 *wpa_ie, size_t wpa_ie_len,
|
const u8 *wpa_ie, size_t wpa_ie_len,
|
||||||
struct wpa_ptk *ptk)
|
struct wpa_ptk *ptk)
|
||||||
{
|
{
|
||||||
size_t rlen;
|
size_t mic_len, hdrlen, rlen;
|
||||||
struct wpa_eapol_key *reply;
|
struct wpa_eapol_key *reply;
|
||||||
u8 *rbuf;
|
struct wpa_eapol_key_192 *reply192;
|
||||||
|
u8 *rbuf, *key_mic;
|
||||||
u8 *rsn_ie_buf = NULL;
|
u8 *rsn_ie_buf = NULL;
|
||||||
|
|
||||||
if (wpa_ie == NULL) {
|
if (wpa_ie == NULL) {
|
||||||
|
@ -349,13 +360,16 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
|
||||||
|
|
||||||
wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);
|
wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);
|
||||||
|
|
||||||
|
mic_len = wpa_mic_len(sm->key_mgmt);
|
||||||
|
hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply);
|
||||||
rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
|
rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
|
||||||
NULL, sizeof(*reply) + wpa_ie_len,
|
NULL, hdrlen + wpa_ie_len,
|
||||||
&rlen, (void *) &reply);
|
&rlen, (void *) &reply);
|
||||||
if (rbuf == NULL) {
|
if (rbuf == NULL) {
|
||||||
os_free(rsn_ie_buf);
|
os_free(rsn_ie_buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
reply192 = (struct wpa_eapol_key_192 *) reply;
|
||||||
|
|
||||||
reply->type = (sm->proto == WPA_PROTO_RSN ||
|
reply->type = (sm->proto == WPA_PROTO_RSN ||
|
||||||
sm->proto == WPA_PROTO_OSEN) ?
|
sm->proto == WPA_PROTO_OSEN) ?
|
||||||
|
@ -371,15 +385,21 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
|
||||||
wpa_hexdump(MSG_DEBUG, "WPA: Replay Counter", reply->replay_counter,
|
wpa_hexdump(MSG_DEBUG, "WPA: Replay Counter", reply->replay_counter,
|
||||||
WPA_REPLAY_COUNTER_LEN);
|
WPA_REPLAY_COUNTER_LEN);
|
||||||
|
|
||||||
|
key_mic = reply192->key_mic; /* same offset for reply and reply192 */
|
||||||
|
if (mic_len == 24) {
|
||||||
|
WPA_PUT_BE16(reply192->key_data_length, wpa_ie_len);
|
||||||
|
os_memcpy(reply192 + 1, wpa_ie, wpa_ie_len);
|
||||||
|
} else {
|
||||||
WPA_PUT_BE16(reply->key_data_length, wpa_ie_len);
|
WPA_PUT_BE16(reply->key_data_length, wpa_ie_len);
|
||||||
os_memcpy(reply + 1, wpa_ie, wpa_ie_len);
|
os_memcpy(reply + 1, wpa_ie, wpa_ie_len);
|
||||||
|
}
|
||||||
os_free(rsn_ie_buf);
|
os_free(rsn_ie_buf);
|
||||||
|
|
||||||
os_memcpy(reply->key_nonce, nonce, WPA_NONCE_LEN);
|
os_memcpy(reply->key_nonce, nonce, WPA_NONCE_LEN);
|
||||||
|
|
||||||
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/4");
|
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/4");
|
||||||
wpa_eapol_key_send(sm, ptk->kck, ptk->kck_len, ver, dst, ETH_P_EAPOL,
|
wpa_eapol_key_send(sm, ptk->kck, ptk->kck_len, ver, dst, ETH_P_EAPOL,
|
||||||
rbuf, rlen, reply->key_mic);
|
rbuf, rlen, key_mic);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1062,14 +1082,18 @@ int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst,
|
||||||
u16 ver, u16 key_info,
|
u16 ver, u16 key_info,
|
||||||
struct wpa_ptk *ptk)
|
struct wpa_ptk *ptk)
|
||||||
{
|
{
|
||||||
size_t rlen;
|
size_t mic_len, hdrlen, rlen;
|
||||||
struct wpa_eapol_key *reply;
|
struct wpa_eapol_key *reply;
|
||||||
u8 *rbuf;
|
struct wpa_eapol_key_192 *reply192;
|
||||||
|
u8 *rbuf, *key_mic;
|
||||||
|
|
||||||
|
mic_len = wpa_mic_len(sm->key_mgmt);
|
||||||
|
hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply);
|
||||||
rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
|
rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
|
||||||
sizeof(*reply), &rlen, (void *) &reply);
|
hdrlen, &rlen, (void *) &reply);
|
||||||
if (rbuf == NULL)
|
if (rbuf == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
reply192 = (struct wpa_eapol_key_192 *) reply;
|
||||||
|
|
||||||
reply->type = (sm->proto == WPA_PROTO_RSN ||
|
reply->type = (sm->proto == WPA_PROTO_RSN ||
|
||||||
sm->proto == WPA_PROTO_OSEN) ?
|
sm->proto == WPA_PROTO_OSEN) ?
|
||||||
|
@ -1084,11 +1108,15 @@ int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst,
|
||||||
os_memcpy(reply->replay_counter, key->replay_counter,
|
os_memcpy(reply->replay_counter, key->replay_counter,
|
||||||
WPA_REPLAY_COUNTER_LEN);
|
WPA_REPLAY_COUNTER_LEN);
|
||||||
|
|
||||||
|
key_mic = reply192->key_mic; /* same offset for reply and reply192 */
|
||||||
|
if (mic_len == 24)
|
||||||
|
WPA_PUT_BE16(reply192->key_data_length, 0);
|
||||||
|
else
|
||||||
WPA_PUT_BE16(reply->key_data_length, 0);
|
WPA_PUT_BE16(reply->key_data_length, 0);
|
||||||
|
|
||||||
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 4/4");
|
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 4/4");
|
||||||
wpa_eapol_key_send(sm, ptk->kck, ptk->kck_len, ver, dst, ETH_P_EAPOL,
|
wpa_eapol_key_send(sm, ptk->kck, ptk->kck_len, ver, dst, ETH_P_EAPOL,
|
||||||
rbuf, rlen, reply->key_mic);
|
rbuf, rlen, key_mic);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1358,14 +1386,18 @@ static int wpa_supplicant_send_2_of_2(struct wpa_sm *sm,
|
||||||
const struct wpa_eapol_key *key,
|
const struct wpa_eapol_key *key,
|
||||||
int ver, u16 key_info)
|
int ver, u16 key_info)
|
||||||
{
|
{
|
||||||
size_t rlen;
|
size_t mic_len, hdrlen, rlen;
|
||||||
struct wpa_eapol_key *reply;
|
struct wpa_eapol_key *reply;
|
||||||
u8 *rbuf;
|
struct wpa_eapol_key_192 *reply192;
|
||||||
|
u8 *rbuf, *key_mic;
|
||||||
|
|
||||||
|
mic_len = wpa_mic_len(sm->key_mgmt);
|
||||||
|
hdrlen = mic_len == 24 ? sizeof(*reply192) : sizeof(*reply);
|
||||||
rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
|
rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
|
||||||
sizeof(*reply), &rlen, (void *) &reply);
|
hdrlen, &rlen, (void *) &reply);
|
||||||
if (rbuf == NULL)
|
if (rbuf == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
reply192 = (struct wpa_eapol_key_192 *) reply;
|
||||||
|
|
||||||
reply->type = (sm->proto == WPA_PROTO_RSN ||
|
reply->type = (sm->proto == WPA_PROTO_RSN ||
|
||||||
sm->proto == WPA_PROTO_OSEN) ?
|
sm->proto == WPA_PROTO_OSEN) ?
|
||||||
|
@ -1380,11 +1412,15 @@ static int wpa_supplicant_send_2_of_2(struct wpa_sm *sm,
|
||||||
os_memcpy(reply->replay_counter, key->replay_counter,
|
os_memcpy(reply->replay_counter, key->replay_counter,
|
||||||
WPA_REPLAY_COUNTER_LEN);
|
WPA_REPLAY_COUNTER_LEN);
|
||||||
|
|
||||||
|
key_mic = reply192->key_mic; /* same offset for reply and reply192 */
|
||||||
|
if (mic_len == 24)
|
||||||
|
WPA_PUT_BE16(reply192->key_data_length, 0);
|
||||||
|
else
|
||||||
WPA_PUT_BE16(reply->key_data_length, 0);
|
WPA_PUT_BE16(reply->key_data_length, 0);
|
||||||
|
|
||||||
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/2");
|
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/2");
|
||||||
wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver, sm->bssid,
|
wpa_eapol_key_send(sm, sm->ptk.kck, sm->ptk.kck_len, ver, sm->bssid,
|
||||||
ETH_P_EAPOL, rbuf, rlen, reply->key_mic);
|
ETH_P_EAPOL, rbuf, rlen, key_mic);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1451,13 +1487,13 @@ failed:
|
||||||
|
|
||||||
|
|
||||||
static int wpa_supplicant_verify_eapol_key_mic(struct wpa_sm *sm,
|
static int wpa_supplicant_verify_eapol_key_mic(struct wpa_sm *sm,
|
||||||
struct wpa_eapol_key *key,
|
struct wpa_eapol_key_192 *key,
|
||||||
u16 ver,
|
u16 ver,
|
||||||
const u8 *buf, size_t len)
|
const u8 *buf, size_t len)
|
||||||
{
|
{
|
||||||
u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
|
u8 mic[WPA_EAPOL_KEY_MIC_MAX_LEN];
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
size_t mic_len = 16;
|
size_t mic_len = wpa_mic_len(sm->key_mgmt);
|
||||||
|
|
||||||
os_memcpy(mic, key->key_mic, mic_len);
|
os_memcpy(mic, key->key_mic, mic_len);
|
||||||
if (sm->tptk_set) {
|
if (sm->tptk_set) {
|
||||||
|
@ -1586,7 +1622,9 @@ void wpa_sm_aborted_cached(struct wpa_sm *sm)
|
||||||
|
|
||||||
|
|
||||||
static void wpa_eapol_key_dump(struct wpa_sm *sm,
|
static void wpa_eapol_key_dump(struct wpa_sm *sm,
|
||||||
const struct wpa_eapol_key *key)
|
const struct wpa_eapol_key *key,
|
||||||
|
unsigned int key_data_len,
|
||||||
|
const u8 *mic, unsigned int mic_len)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_NO_STDOUT_DEBUG
|
#ifndef CONFIG_NO_STDOUT_DEBUG
|
||||||
u16 key_info = WPA_GET_BE16(key->key_info);
|
u16 key_info = WPA_GET_BE16(key->key_info);
|
||||||
|
@ -1608,15 +1646,14 @@ static void wpa_eapol_key_dump(struct wpa_sm *sm,
|
||||||
key_info & WPA_KEY_INFO_ENCR_KEY_DATA ? " Encr" : "");
|
key_info & WPA_KEY_INFO_ENCR_KEY_DATA ? " Encr" : "");
|
||||||
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
|
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
|
||||||
" key_length=%u key_data_length=%u",
|
" key_length=%u key_data_length=%u",
|
||||||
WPA_GET_BE16(key->key_length),
|
WPA_GET_BE16(key->key_length), key_data_len);
|
||||||
WPA_GET_BE16(key->key_data_length));
|
|
||||||
wpa_hexdump(MSG_DEBUG, " replay_counter",
|
wpa_hexdump(MSG_DEBUG, " replay_counter",
|
||||||
key->replay_counter, WPA_REPLAY_COUNTER_LEN);
|
key->replay_counter, WPA_REPLAY_COUNTER_LEN);
|
||||||
wpa_hexdump(MSG_DEBUG, " key_nonce", key->key_nonce, WPA_NONCE_LEN);
|
wpa_hexdump(MSG_DEBUG, " key_nonce", key->key_nonce, WPA_NONCE_LEN);
|
||||||
wpa_hexdump(MSG_DEBUG, " key_iv", key->key_iv, 16);
|
wpa_hexdump(MSG_DEBUG, " key_iv", key->key_iv, 16);
|
||||||
wpa_hexdump(MSG_DEBUG, " key_rsc", key->key_rsc, 8);
|
wpa_hexdump(MSG_DEBUG, " key_rsc", key->key_rsc, 8);
|
||||||
wpa_hexdump(MSG_DEBUG, " key_id (reserved)", key->key_id, 8);
|
wpa_hexdump(MSG_DEBUG, " key_id (reserved)", key->key_id, 8);
|
||||||
wpa_hexdump(MSG_DEBUG, " key_mic", key->key_mic, 16);
|
wpa_hexdump(MSG_DEBUG, " key_mic", mic, mic_len);
|
||||||
#endif /* CONFIG_NO_STDOUT_DEBUG */
|
#endif /* CONFIG_NO_STDOUT_DEBUG */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1643,22 +1680,27 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
|
||||||
size_t plen, data_len, key_data_len;
|
size_t plen, data_len, key_data_len;
|
||||||
const struct ieee802_1x_hdr *hdr;
|
const struct ieee802_1x_hdr *hdr;
|
||||||
struct wpa_eapol_key *key;
|
struct wpa_eapol_key *key;
|
||||||
|
struct wpa_eapol_key_192 *key192;
|
||||||
u16 key_info, ver;
|
u16 key_info, ver;
|
||||||
u8 *tmp = NULL;
|
u8 *tmp = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
struct wpa_peerkey *peerkey = NULL;
|
struct wpa_peerkey *peerkey = NULL;
|
||||||
u8 *key_data;
|
u8 *key_data;
|
||||||
|
size_t mic_len, keyhdrlen;
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE80211R
|
#ifdef CONFIG_IEEE80211R
|
||||||
sm->ft_completed = 0;
|
sm->ft_completed = 0;
|
||||||
#endif /* CONFIG_IEEE80211R */
|
#endif /* CONFIG_IEEE80211R */
|
||||||
|
|
||||||
if (len < sizeof(*hdr) + sizeof(*key)) {
|
mic_len = wpa_mic_len(sm->key_mgmt);
|
||||||
|
keyhdrlen = mic_len == 24 ? sizeof(*key192) : sizeof(*key);
|
||||||
|
|
||||||
|
if (len < sizeof(*hdr) + keyhdrlen) {
|
||||||
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
|
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
|
||||||
"WPA: EAPOL frame too short to be a WPA "
|
"WPA: EAPOL frame too short to be a WPA "
|
||||||
"EAPOL-Key (len %lu, expecting at least %lu)",
|
"EAPOL-Key (len %lu, expecting at least %lu)",
|
||||||
(unsigned long) len,
|
(unsigned long) len,
|
||||||
(unsigned long) sizeof(*hdr) + sizeof(*key));
|
(unsigned long) sizeof(*hdr) + keyhdrlen);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1680,7 +1722,7 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL-Key", buf, len);
|
wpa_hexdump(MSG_MSGDUMP, "WPA: RX EAPOL-Key", buf, len);
|
||||||
if (plen > len - sizeof(*hdr) || plen < sizeof(*key)) {
|
if (plen > len - sizeof(*hdr) || plen < keyhdrlen) {
|
||||||
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
|
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
|
||||||
"WPA: EAPOL frame payload size %lu "
|
"WPA: EAPOL frame payload size %lu "
|
||||||
"invalid (frame size %lu)",
|
"invalid (frame size %lu)",
|
||||||
|
@ -1703,6 +1745,11 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
|
||||||
goto out;
|
goto out;
|
||||||
os_memcpy(tmp, buf, data_len);
|
os_memcpy(tmp, buf, data_len);
|
||||||
key = (struct wpa_eapol_key *) (tmp + sizeof(struct ieee802_1x_hdr));
|
key = (struct wpa_eapol_key *) (tmp + sizeof(struct ieee802_1x_hdr));
|
||||||
|
key192 = (struct wpa_eapol_key_192 *)
|
||||||
|
(tmp + sizeof(struct ieee802_1x_hdr));
|
||||||
|
if (mic_len == 24)
|
||||||
|
key_data = (u8 *) (key192 + 1);
|
||||||
|
else
|
||||||
key_data = (u8 *) (key + 1);
|
key_data = (u8 *) (key + 1);
|
||||||
|
|
||||||
if (key->type != EAPOL_KEY_TYPE_WPA && key->type != EAPOL_KEY_TYPE_RSN)
|
if (key->type != EAPOL_KEY_TYPE_WPA && key->type != EAPOL_KEY_TYPE_RSN)
|
||||||
|
@ -1713,14 +1760,18 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
wpa_eapol_key_dump(sm, key);
|
|
||||||
|
|
||||||
|
if (mic_len == 24)
|
||||||
|
key_data_len = WPA_GET_BE16(key192->key_data_length);
|
||||||
|
else
|
||||||
key_data_len = WPA_GET_BE16(key->key_data_length);
|
key_data_len = WPA_GET_BE16(key->key_data_length);
|
||||||
if (key_data_len > plen - sizeof(struct wpa_eapol_key)) {
|
wpa_eapol_key_dump(sm, key, key_data_len, key192->key_mic, mic_len);
|
||||||
|
|
||||||
|
if (key_data_len > plen - keyhdrlen) {
|
||||||
wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Invalid EAPOL-Key "
|
wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Invalid EAPOL-Key "
|
||||||
"frame - key_data overflow (%u > %u)",
|
"frame - key_data overflow (%u > %u)",
|
||||||
(unsigned int) key_data_len,
|
(unsigned int) key_data_len,
|
||||||
(unsigned int) (plen - sizeof(struct wpa_eapol_key)));
|
(unsigned int) (plen - keyhdrlen));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1870,12 +1921,13 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((key_info & WPA_KEY_INFO_MIC) && !peerkey &&
|
if ((key_info & WPA_KEY_INFO_MIC) && !peerkey &&
|
||||||
wpa_supplicant_verify_eapol_key_mic(sm, key, ver, tmp, data_len))
|
wpa_supplicant_verify_eapol_key_mic(sm, key192, ver, tmp, data_len))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
#ifdef CONFIG_PEERKEY
|
#ifdef CONFIG_PEERKEY
|
||||||
if ((key_info & WPA_KEY_INFO_MIC) && peerkey &&
|
if ((key_info & WPA_KEY_INFO_MIC) && peerkey &&
|
||||||
peerkey_verify_eapol_key_mic(sm, peerkey, key, ver, tmp, data_len))
|
peerkey_verify_eapol_key_mic(sm, peerkey, key192, ver, tmp,
|
||||||
|
data_len))
|
||||||
goto out;
|
goto out;
|
||||||
#endif /* CONFIG_PEERKEY */
|
#endif /* CONFIG_PEERKEY */
|
||||||
|
|
||||||
|
@ -1965,6 +2017,8 @@ static u32 wpa_key_mgmt_suite(struct wpa_sm *sm)
|
||||||
return WPA_AUTH_KEY_MGMT_NONE;
|
return WPA_AUTH_KEY_MGMT_NONE;
|
||||||
case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
|
case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
|
||||||
return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
|
return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B;
|
||||||
|
case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
|
||||||
|
return RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* wpa_supplicant - WPA/RSN IE and KDE processing
|
* wpa_supplicant - WPA/RSN IE and KDE processing
|
||||||
* Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -173,6 +173,8 @@ static int wpa_gen_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
|
||||||
} else if (key_mgmt == WPA_KEY_MGMT_FT_SAE) {
|
} else if (key_mgmt == WPA_KEY_MGMT_FT_SAE) {
|
||||||
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE);
|
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE);
|
||||||
#endif /* CONFIG_SAE */
|
#endif /* CONFIG_SAE */
|
||||||
|
} else if (key_mgmt == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
|
||||||
|
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192);
|
||||||
} else if (key_mgmt == WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
|
} else if (key_mgmt == WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
|
||||||
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B);
|
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* wlantest control interface
|
* wlantest control interface
|
||||||
* Copyright (c) 2010-2013, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2010-2015, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -954,6 +954,9 @@ static void info_print_key_mgmt(char *buf, size_t len, int key_mgmt)
|
||||||
if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
|
if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
|
||||||
pos += os_snprintf(pos, end - pos, "%sEAP-SUITE-B",
|
pos += os_snprintf(pos, end - pos, "%sEAP-SUITE-B",
|
||||||
pos == buf ? "" : " ");
|
pos == buf ? "" : " ");
|
||||||
|
if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
|
||||||
|
pos += os_snprintf(pos, end - pos, "%sEAP-SUITE-B-192",
|
||||||
|
pos == buf ? "" : " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* STA list
|
* STA list
|
||||||
* Copyright (c) 2010, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2010-2015, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -170,7 +170,7 @@ skip_rsn_wpa:
|
||||||
wpa_printf(MSG_INFO, "STA " MACSTR
|
wpa_printf(MSG_INFO, "STA " MACSTR
|
||||||
" proto=%s%s%s%s"
|
" proto=%s%s%s%s"
|
||||||
"pairwise=%s%s%s%s%s%s%s"
|
"pairwise=%s%s%s%s%s%s%s"
|
||||||
"key_mgmt=%s%s%s%s%s%s%s%s%s%s"
|
"key_mgmt=%s%s%s%s%s%s%s%s%s%s%s"
|
||||||
"rsn_capab=%s%s%s%s%s",
|
"rsn_capab=%s%s%s%s%s",
|
||||||
MAC2STR(sta->addr),
|
MAC2STR(sta->addr),
|
||||||
sta->proto == 0 ? "OPEN " : "",
|
sta->proto == 0 ? "OPEN " : "",
|
||||||
|
@ -199,6 +199,8 @@ skip_rsn_wpa:
|
||||||
sta->key_mgmt & WPA_KEY_MGMT_OSEN ? "OSEN " : "",
|
sta->key_mgmt & WPA_KEY_MGMT_OSEN ? "OSEN " : "",
|
||||||
sta->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B ?
|
sta->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B ?
|
||||||
"EAP-SUITE-B " : "",
|
"EAP-SUITE-B " : "",
|
||||||
|
sta->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192 ?
|
||||||
|
"EAP-SUITE-B-192 " : "",
|
||||||
sta->rsn_capab & WPA_CAPABILITY_PREAUTH ? "PREAUTH " : "",
|
sta->rsn_capab & WPA_CAPABILITY_PREAUTH ? "PREAUTH " : "",
|
||||||
sta->rsn_capab & WPA_CAPABILITY_NO_PAIRWISE ?
|
sta->rsn_capab & WPA_CAPABILITY_NO_PAIRWISE ?
|
||||||
"NO_PAIRWISE " : "",
|
"NO_PAIRWISE " : "",
|
||||||
|
|
|
@ -189,6 +189,11 @@ NEED_SHA256=y
|
||||||
NEED_AES_OMAC1=y
|
NEED_AES_OMAC1=y
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_SUITEB192
|
||||||
|
L_CFLAGS += -DCONFIG_SUITEB192
|
||||||
|
NEED_SHA384=y
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef CONFIG_IEEE80211W
|
ifdef CONFIG_IEEE80211W
|
||||||
L_CFLAGS += -DCONFIG_IEEE80211W
|
L_CFLAGS += -DCONFIG_IEEE80211W
|
||||||
NEED_SHA256=y
|
NEED_SHA256=y
|
||||||
|
|
|
@ -192,6 +192,11 @@ NEED_SHA256=y
|
||||||
NEED_AES_OMAC1=y
|
NEED_AES_OMAC1=y
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_SUITEB192
|
||||||
|
CFLAGS += -DCONFIG_SUITEB192
|
||||||
|
NEED_SHA384=y
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef CONFIG_IEEE80211W
|
ifdef CONFIG_IEEE80211W
|
||||||
CFLAGS += -DCONFIG_IEEE80211W
|
CFLAGS += -DCONFIG_IEEE80211W
|
||||||
NEED_SHA256=y
|
NEED_SHA256=y
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* WPA Supplicant / Configuration parser and common functions
|
* WPA Supplicant / Configuration parser and common functions
|
||||||
* Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -678,8 +678,14 @@ static int wpa_config_parse_key_mgmt(const struct parse_data *data,
|
||||||
else if (os_strcmp(start, "OSEN") == 0)
|
else if (os_strcmp(start, "OSEN") == 0)
|
||||||
val |= WPA_KEY_MGMT_OSEN;
|
val |= WPA_KEY_MGMT_OSEN;
|
||||||
#endif /* CONFIG_HS20 */
|
#endif /* CONFIG_HS20 */
|
||||||
|
#ifdef CONFIG_SUITEB
|
||||||
else if (os_strcmp(start, "WPA-EAP-SUITE-B") == 0)
|
else if (os_strcmp(start, "WPA-EAP-SUITE-B") == 0)
|
||||||
val |= WPA_KEY_MGMT_IEEE8021X_SUITE_B;
|
val |= WPA_KEY_MGMT_IEEE8021X_SUITE_B;
|
||||||
|
#endif /* CONFIG_SUITEB */
|
||||||
|
#ifdef CONFIG_SUITEB192
|
||||||
|
else if (os_strcmp(start, "WPA-EAP-SUITE-B-192") == 0)
|
||||||
|
val |= WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
|
||||||
|
#endif /* CONFIG_SUITEB192 */
|
||||||
else {
|
else {
|
||||||
wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
|
wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
|
||||||
line, start);
|
line, start);
|
||||||
|
@ -856,6 +862,7 @@ static char * wpa_config_write_key_mgmt(const struct parse_data *data,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_HS20 */
|
#endif /* CONFIG_HS20 */
|
||||||
|
|
||||||
|
#ifdef CONFIG_SUITEB
|
||||||
if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
|
if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
|
||||||
ret = os_snprintf(pos, end - pos, "%sWPA-EAP-SUITE-B",
|
ret = os_snprintf(pos, end - pos, "%sWPA-EAP-SUITE-B",
|
||||||
pos == buf ? "" : " ");
|
pos == buf ? "" : " ");
|
||||||
|
@ -865,6 +872,19 @@ static char * wpa_config_write_key_mgmt(const struct parse_data *data,
|
||||||
}
|
}
|
||||||
pos += ret;
|
pos += ret;
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_SUITEB */
|
||||||
|
|
||||||
|
#ifdef CONFIG_SUITEB192
|
||||||
|
if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
|
||||||
|
ret = os_snprintf(pos, end - pos, "%sWPA-EAP-SUITE-B-192",
|
||||||
|
pos == buf ? "" : " ");
|
||||||
|
if (os_snprintf_error(end - pos, ret)) {
|
||||||
|
end[-1] = '\0';
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
pos += ret;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_SUITEB192 */
|
||||||
|
|
||||||
if (pos == buf) {
|
if (pos == buf) {
|
||||||
os_free(buf);
|
os_free(buf);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* WPA Supplicant / Control interface (shared code for all backends)
|
* WPA Supplicant / Control interface (shared code for all backends)
|
||||||
* Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -2323,6 +2323,7 @@ static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_IEEE80211W */
|
#endif /* CONFIG_IEEE80211W */
|
||||||
|
|
||||||
|
#ifdef CONFIG_SUITEB
|
||||||
if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
|
if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
|
||||||
ret = os_snprintf(pos, end - pos, "%sEAP-SUITE-B",
|
ret = os_snprintf(pos, end - pos, "%sEAP-SUITE-B",
|
||||||
pos == start ? "" : "+");
|
pos == start ? "" : "+");
|
||||||
|
@ -2330,6 +2331,17 @@ static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto,
|
||||||
return pos;
|
return pos;
|
||||||
pos += ret;
|
pos += ret;
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_SUITEB */
|
||||||
|
|
||||||
|
#ifdef CONFIG_SUITEB192
|
||||||
|
if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
|
||||||
|
ret = os_snprintf(pos, end - pos, "%sEAP-SUITE-B-192",
|
||||||
|
pos == start ? "" : "+");
|
||||||
|
if (os_snprintf_error(end - pos, ret))
|
||||||
|
return pos;
|
||||||
|
pos += ret;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_SUITEB192 */
|
||||||
|
|
||||||
pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher);
|
pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* WPA Supplicant / dbus-based control interface
|
* WPA Supplicant / dbus-based control interface
|
||||||
* Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
|
* Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
|
||||||
* Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com>
|
* Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com>
|
||||||
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2009-2015, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -3590,7 +3590,7 @@ static dbus_bool_t wpas_dbus_get_bss_security_prop(DBusMessageIter *iter,
|
||||||
DBusMessageIter iter_dict, variant_iter;
|
DBusMessageIter iter_dict, variant_iter;
|
||||||
const char *group;
|
const char *group;
|
||||||
const char *pairwise[5]; /* max 5 pairwise ciphers is supported */
|
const char *pairwise[5]; /* max 5 pairwise ciphers is supported */
|
||||||
const char *key_mgmt[8]; /* max 8 key managements may be supported */
|
const char *key_mgmt[9]; /* max 9 key managements may be supported */
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
|
if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
|
||||||
|
@ -3614,8 +3614,14 @@ static dbus_bool_t wpas_dbus_get_bss_security_prop(DBusMessageIter *iter,
|
||||||
key_mgmt[n++] = "wpa-ft-eap";
|
key_mgmt[n++] = "wpa-ft-eap";
|
||||||
if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
|
if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
|
||||||
key_mgmt[n++] = "wpa-eap-sha256";
|
key_mgmt[n++] = "wpa-eap-sha256";
|
||||||
|
#ifdef CONFIG_SUITEB
|
||||||
if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
|
if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
|
||||||
key_mgmt[n++] = "wpa-eap-suite-b";
|
key_mgmt[n++] = "wpa-eap-suite-b";
|
||||||
|
#endif /* CONFIG_SUITEB */
|
||||||
|
#ifdef CONFIG_SUITEB192
|
||||||
|
if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
|
||||||
|
key_mgmt[n++] = "wpa-eap-suite-b-192";
|
||||||
|
#endif /* CONFIG_SUITEB192 */
|
||||||
if (ie_data->key_mgmt & WPA_KEY_MGMT_NONE)
|
if (ie_data->key_mgmt & WPA_KEY_MGMT_NONE)
|
||||||
key_mgmt[n++] = "wpa-none";
|
key_mgmt[n++] = "wpa-none";
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* WPA Supplicant
|
* WPA Supplicant
|
||||||
* Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -1138,10 +1138,18 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
|
||||||
sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
|
sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
|
||||||
#endif /* CONFIG_SAE */
|
#endif /* CONFIG_SAE */
|
||||||
if (0) {
|
if (0) {
|
||||||
|
#ifdef CONFIG_SUITEB192
|
||||||
|
} else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
|
||||||
|
wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
|
||||||
|
wpa_dbg(wpa_s, MSG_DEBUG,
|
||||||
|
"WPA: using KEY_MGMT 802.1X with Suite B (192-bit)");
|
||||||
|
#endif /* CONFIG_SUITEB192 */
|
||||||
|
#ifdef CONFIG_SUITEB
|
||||||
} else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
|
} else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
|
||||||
wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B;
|
wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B;
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG,
|
wpa_dbg(wpa_s, MSG_DEBUG,
|
||||||
"WPA: using KEY_MGMT 802.1X with Suite B");
|
"WPA: using KEY_MGMT 802.1X with Suite B");
|
||||||
|
#endif /* CONFIG_SUITEB */
|
||||||
#ifdef CONFIG_IEEE80211R
|
#ifdef CONFIG_IEEE80211R
|
||||||
} else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
|
} else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
|
||||||
wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
|
wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
|
||||||
|
@ -2143,7 +2151,8 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
|
||||||
if (wpa_s->conf->key_mgmt_offload) {
|
if (wpa_s->conf->key_mgmt_offload) {
|
||||||
if (params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
|
if (params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
|
||||||
params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
|
params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
|
||||||
params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B)
|
params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B ||
|
||||||
|
params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
|
||||||
params.req_key_mgmt_offload =
|
params.req_key_mgmt_offload =
|
||||||
ssid->proactive_key_caching < 0 ?
|
ssid->proactive_key_caching < 0 ?
|
||||||
wpa_s->conf->okc : ssid->proactive_key_caching;
|
wpa_s->conf->okc : ssid->proactive_key_caching;
|
||||||
|
|
Loading…
Reference in a new issue