Remove all PeerKey functionality

This was originally added to allow the IEEE 802.11 protocol to be
tested, but there are no known fully functional implementations based on
this nor any known deployments of PeerKey functionality. Furthermore,
PeerKey design in the IEEE Std 802.11-2016 standard has already been
marked as obsolete for DLS and it is being considered for complete
removal in REVmd.

This implementation did not really work, so it could not have been used
in practice. For example, key configuration was using incorrect
algorithm values (WPA_CIPHER_* instead of WPA_ALG_*) which resulted in
mapping to an invalid WPA_ALG_* value for the actual driver operation.
As such, the derived key could not have been successfully set for the
link.

Since there are bugs in this implementation and there does not seem to
be any future for the PeerKey design with DLS (TDLS being the future for
DLS), the best approach is to simply delete all this code to simplify
the EAPOL-Key handling design and to get rid of any potential issues if
these code paths were accidentially reachable.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2017-09-22 14:59:13 +03:00
parent 2956fcc401
commit a0bf1b68c0
45 changed files with 43 additions and 2092 deletions

View file

@ -10,7 +10,6 @@ include ../lib.rules
CFLAGS += -DCONFIG_IEEE80211W
CFLAGS += -DCONFIG_IEEE80211R
CFLAGS += -DCONFIG_PEERKEY
CFLAGS += -DCONFIG_TDLS
CFLAGS += -DCONFIG_WNM
CFLAGS += -DIEEE8021X_EAPOL
@ -18,7 +17,6 @@ CFLAGS += -DIEEE8021X_EAPOL
LIB_OBJS= \
pmksa_cache.o \
wpa_ft.o \
peerkey.o \
tdls.o \
preauth.o \
wpa.o \

File diff suppressed because it is too large Load diff

View file

@ -1,82 +0,0 @@
/*
* WPA Supplicant - PeerKey for Direct Link Setup (DLS)
* Copyright (c) 2006-2015, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef PEERKEY_H
#define PEERKEY_H
#define PEERKEY_MAX_IE_LEN 80
struct wpa_peerkey {
struct wpa_peerkey *next;
int initiator; /* whether this end was initator for SMK handshake */
u8 addr[ETH_ALEN]; /* other end MAC address */
u8 inonce[WPA_NONCE_LEN]; /* Initiator Nonce */
u8 pnonce[WPA_NONCE_LEN]; /* Peer Nonce */
u8 rsnie_i[PEERKEY_MAX_IE_LEN]; /* Initiator RSN IE */
size_t rsnie_i_len;
u8 rsnie_p[PEERKEY_MAX_IE_LEN]; /* Peer RSN IE */
size_t rsnie_p_len;
u8 smk[PMK_LEN];
int smk_complete;
u8 smkid[PMKID_LEN];
u32 lifetime;
int cipher; /* Selected cipher (WPA_CIPHER_*) */
u8 replay_counter[WPA_REPLAY_COUNTER_LEN];
int replay_counter_set;
int akmp;
struct wpa_ptk stk, tstk;
int stk_set, tstk_set;
};
#ifdef CONFIG_PEERKEY
int peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
struct wpa_peerkey *peerkey,
struct wpa_eapol_key *key, u16 ver,
const u8 *buf, size_t len);
void peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey,
struct wpa_eapol_key *key, u16 key_info, u16 ver,
const u8 *key_data, size_t key_data_len);
void peerkey_rx_eapol_smk(struct wpa_sm *sm, const u8 *src_addr,
struct wpa_eapol_key *key, const u8 *key_data,
size_t key_data_len, u16 key_info, u16 ver);
void peerkey_deinit(struct wpa_sm *sm);
#else /* CONFIG_PEERKEY */
static inline int
peerkey_verify_eapol_key_mic(struct wpa_sm *sm,
struct wpa_peerkey *peerkey,
struct wpa_eapol_key *key, u16 ver,
const u8 *buf, size_t len)
{
return -1;
}
static inline void
peerkey_rx_eapol_4way(struct wpa_sm *sm, struct wpa_peerkey *peerkey,
struct wpa_eapol_key *key, u16 key_info, u16 ver,
const u8 *key_data, size_t key_data_len)
{
}
static inline void
peerkey_rx_eapol_smk(struct wpa_sm *sm, const u8 *src_addr,
struct wpa_eapol_key *key, const u8 *key_data,
size_t key_data_len, u16 key_info, u16 ver)
{
}
static inline void peerkey_deinit(struct wpa_sm *sm)
{
}
#endif /* CONFIG_PEERKEY */
#endif /* PEERKEY_H */

View file

@ -28,7 +28,6 @@
#include "pmksa_cache.h"
#include "wpa_i.h"
#include "wpa_ie.h"
#include "peerkey.h"
static const u8 null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
@ -1988,7 +1987,6 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
u16 key_info, ver;
u8 *tmp = NULL;
int ret = -1;
struct wpa_peerkey *peerkey = NULL;
u8 *mic, *key_data;
size_t mic_len, keyhdrlen;
@ -2164,44 +2162,7 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
goto out;
}
#ifdef CONFIG_PEERKEY
for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0)
break;
}
if (!(key_info & WPA_KEY_INFO_SMK_MESSAGE) && peerkey) {
if (!peerkey->initiator && peerkey->replay_counter_set &&
os_memcmp(key->replay_counter, peerkey->replay_counter,
WPA_REPLAY_COUNTER_LEN) <= 0) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
"RSN: EAPOL-Key Replay Counter did not "
"increase (STK) - dropping packet");
goto out;
} else if (peerkey->initiator) {
u8 _tmp[WPA_REPLAY_COUNTER_LEN];
os_memcpy(_tmp, key->replay_counter,
WPA_REPLAY_COUNTER_LEN);
inc_byte_array(_tmp, WPA_REPLAY_COUNTER_LEN);
if (os_memcmp(_tmp, peerkey->replay_counter,
WPA_REPLAY_COUNTER_LEN) != 0) {
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
"RSN: EAPOL-Key Replay "
"Counter did not match (STK) - "
"dropping packet");
goto out;
}
}
}
if (peerkey && peerkey->initiator && (key_info & WPA_KEY_INFO_ACK)) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"RSN: Ack bit in key_info from STK peer");
goto out;
}
#endif /* CONFIG_PEERKEY */
if (!peerkey && sm->rx_replay_counter_set &&
if (sm->rx_replay_counter_set &&
os_memcmp(key->replay_counter, sm->rx_replay_counter,
WPA_REPLAY_COUNTER_LEN) <= 0) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
@ -2210,11 +2171,13 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
goto out;
}
if (!(key_info & (WPA_KEY_INFO_ACK | WPA_KEY_INFO_SMK_MESSAGE))
#ifdef CONFIG_PEERKEY
&& (peerkey == NULL || !peerkey->initiator)
#endif /* CONFIG_PEERKEY */
) {
if (key_info & WPA_KEY_INFO_SMK_MESSAGE) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"WPA: Unsupported SMK bit in key_info");
goto out;
}
if (!(key_info & WPA_KEY_INFO_ACK)) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"WPA: No Ack bit in key_info");
goto out;
@ -2226,17 +2189,10 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
goto out;
}
if ((key_info & WPA_KEY_INFO_MIC) && !peerkey &&
if ((key_info & WPA_KEY_INFO_MIC) &&
wpa_supplicant_verify_eapol_key_mic(sm, key, ver, tmp, data_len))
goto out;
#ifdef CONFIG_PEERKEY
if ((key_info & WPA_KEY_INFO_MIC) && peerkey &&
peerkey_verify_eapol_key_mic(sm, peerkey, key, ver, tmp,
data_len))
goto out;
#endif /* CONFIG_PEERKEY */
#ifdef CONFIG_FILS
if (!mic_len && (key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
if (wpa_supp_aead_decrypt(sm, tmp, data_len, &key_data_len))
@ -2259,12 +2215,8 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
"non-zero key index");
goto out;
}
if (peerkey) {
/* PeerKey 4-Way Handshake */
peerkey_rx_eapol_4way(sm, peerkey, key, key_info, ver,
key_data, key_data_len);
} else if (key_info & (WPA_KEY_INFO_MIC |
WPA_KEY_INFO_ENCR_KEY_DATA)) {
if (key_info & (WPA_KEY_INFO_MIC |
WPA_KEY_INFO_ENCR_KEY_DATA)) {
/* 3/4 4-Way Handshake */
wpa_supplicant_process_3_of_4(sm, key, ver, key_data,
key_data_len);
@ -2274,10 +2226,6 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
ver, key_data,
key_data_len);
}
} else if (key_info & WPA_KEY_INFO_SMK_MESSAGE) {
/* PeerKey SMK Handshake */
peerkey_rx_eapol_smk(sm, src_addr, key, key_data, key_data_len,
key_info, ver);
} else {
if ((mic_len && (key_info & WPA_KEY_INFO_MIC)) ||
(!mic_len && (key_info & WPA_KEY_INFO_ENCR_KEY_DATA))) {
@ -2519,7 +2467,6 @@ void wpa_sm_deinit(struct wpa_sm *sm)
os_free(sm->ap_rsn_ie);
wpa_sm_drop_sa(sm);
os_free(sm->ctx);
peerkey_deinit(sm);
#ifdef CONFIG_IEEE80211R
os_free(sm->assoc_resp_ies);
#endif /* CONFIG_IEEE80211R */
@ -2628,7 +2575,6 @@ void wpa_sm_notify_disassoc(struct wpa_sm *sm)
{
eloop_cancel_timeout(wpa_sm_start_preauth, sm, NULL);
eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL);
peerkey_deinit(sm);
rsn_preauth_deinit(sm);
pmksa_cache_clear_current(sm);
if (wpa_sm_get_state(sm) == WPA_4WAY_HANDSHAKE)
@ -2748,7 +2694,6 @@ void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config)
if (config) {
sm->network_ctx = config->network_ctx;
sm->peerkey_enabled = config->peerkey_enabled;
sm->allowed_pairwise_cipher = config->allowed_pairwise_cipher;
sm->proactive_key_caching = config->proactive_key_caching;
sm->eap_workaround = config->eap_workaround;
@ -2772,7 +2717,6 @@ void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config)
#endif /* CONFIG_FILS */
} else {
sm->network_ctx = NULL;
sm->peerkey_enabled = 0;
sm->allowed_pairwise_cipher = 0;
sm->proactive_key_caching = 0;
sm->eap_workaround = 0;
@ -3278,27 +3222,6 @@ int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf)
#endif /* CONFIG_WNM */
#ifdef CONFIG_PEERKEY
int wpa_sm_rx_eapol_peerkey(struct wpa_sm *sm, const u8 *src_addr,
const u8 *buf, size_t len)
{
struct wpa_peerkey *peerkey;
for (peerkey = sm->peerkey; peerkey; peerkey = peerkey->next) {
if (os_memcmp(peerkey->addr, src_addr, ETH_ALEN) == 0)
break;
}
if (!peerkey)
return 0;
wpa_sm_rx_eapol(sm, src_addr, buf, len);
return 1;
}
#endif /* CONFIG_PEERKEY */
#ifdef CONFIG_P2P
int wpa_sm_get_p2p_ip_addr(struct wpa_sm *sm, u8 *buf)

View file

@ -100,7 +100,6 @@ enum wpa_sm_conf_params {
struct rsn_supp_config {
void *network_ctx;
int peerkey_enabled;
int allowed_pairwise_cipher; /* bitfield of WPA_CIPHER_* */
int proactive_key_caching;
int eap_workaround;
@ -350,23 +349,6 @@ static inline int wpa_fils_is_completed(struct wpa_sm *sm)
#endif /* CONFIG_NO_WPA */
#ifdef CONFIG_PEERKEY
int wpa_sm_stkstart(struct wpa_sm *sm, const u8 *peer);
int wpa_sm_rx_eapol_peerkey(struct wpa_sm *sm, const u8 *src_addr,
const u8 *buf, size_t len);
#else /* CONFIG_PEERKEY */
static inline int wpa_sm_stkstart(struct wpa_sm *sm, const u8 *peer)
{
return -1;
}
static inline int wpa_sm_rx_eapol_peerkey(struct wpa_sm *sm, const u8 *src_addr,
const u8 *buf, size_t len)
{
return 0;
}
#endif /* CONFIG_PEERKEY */
#ifdef CONFIG_IEEE80211R
int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *ies, size_t ies_len);

View file

@ -11,7 +11,6 @@
#include "utils/list.h"
struct wpa_peerkey;
struct wpa_tdls_peer;
struct wpa_eapol_key;
@ -57,7 +56,6 @@ struct wpa_sm {
int fast_reauth; /* whether EAP fast re-authentication is enabled */
void *network_ctx;
int peerkey_enabled;
int allowed_pairwise_cipher; /* bitfield of WPA_CIPHER_* */
int proactive_key_caching;
int eap_workaround;
@ -94,9 +92,6 @@ struct wpa_sm {
u8 *ap_wpa_ie, *ap_rsn_ie;
size_t ap_wpa_ie_len, ap_rsn_ie_len;
#ifdef CONFIG_PEERKEY
struct wpa_peerkey *peerkey;
#endif /* CONFIG_PEERKEY */
#ifdef CONFIG_TDLS
struct wpa_tdls_peer *tdls;
int tdls_prohibited;

View file

@ -425,44 +425,6 @@ static int wpa_parse_generic(const u8 *pos, const u8 *end,
return 0;
}
#ifdef CONFIG_PEERKEY
if (pos[1] > RSN_SELECTOR_LEN + 2 &&
RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_SMK) {
ie->smk = pos + 2 + RSN_SELECTOR_LEN;
ie->smk_len = pos[1] - RSN_SELECTOR_LEN;
wpa_hexdump_key(MSG_DEBUG, "WPA: SMK in EAPOL-Key",
pos, pos[1] + 2);
return 0;
}
if (pos[1] > RSN_SELECTOR_LEN + 2 &&
RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_NONCE) {
ie->nonce = pos + 2 + RSN_SELECTOR_LEN;
ie->nonce_len = pos[1] - RSN_SELECTOR_LEN;
wpa_hexdump(MSG_DEBUG, "WPA: Nonce in EAPOL-Key",
pos, pos[1] + 2);
return 0;
}
if (pos[1] > RSN_SELECTOR_LEN + 2 &&
RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_LIFETIME) {
ie->lifetime = pos + 2 + RSN_SELECTOR_LEN;
ie->lifetime_len = pos[1] - RSN_SELECTOR_LEN;
wpa_hexdump(MSG_DEBUG, "WPA: Lifetime in EAPOL-Key",
pos, pos[1] + 2);
return 0;
}
if (pos[1] > RSN_SELECTOR_LEN + 2 &&
RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_ERROR) {
ie->error = pos + 2 + RSN_SELECTOR_LEN;
ie->error_len = pos[1] - RSN_SELECTOR_LEN;
wpa_hexdump(MSG_DEBUG, "WPA: Error in EAPOL-Key",
pos, pos[1] + 2);
return 0;
}
#endif /* CONFIG_PEERKEY */
#ifdef CONFIG_IEEE80211W
if (pos[1] > RSN_SELECTOR_LEN + 2 &&
RSN_SELECTOR_GET(pos + 2) == RSN_KEY_DATA_IGTK) {

View file

@ -21,16 +21,6 @@ struct wpa_eapol_ie_parse {
size_t gtk_len;
const u8 *mac_addr;
size_t mac_addr_len;
#ifdef CONFIG_PEERKEY
const u8 *smk;
size_t smk_len;
const u8 *nonce;
size_t nonce_len;
const u8 *lifetime;
size_t lifetime_len;
const u8 *error;
size_t error_len;
#endif /* CONFIG_PEERKEY */
#ifdef CONFIG_IEEE80211W
const u8 *igtk;
size_t igtk_len;