STA: Allow PTK rekeying without Ext KeyID to be disabled as a workaround
Rekeying a pairwise key using only keyid 0 (PTK0 rekey) has many broken implementations and should be avoided when using or interacting with one. The effects can be triggered by either end of the connection and range from hardly noticeable disconnects over long connection freezes up to leaking clear text MPDUs. To allow affected users to mitigate the issues, add a new configuration option "wpa_deny_ptk0_rekey" to replace all PTK0 rekeys with fast reconnects. Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de>
This commit is contained in:
parent
1a7963e36f
commit
1f90a49d02
18 changed files with 174 additions and 8 deletions
|
@ -200,6 +200,15 @@ static void eapol_port_timers_tick(void *eloop_ctx, void *timeout_ctx)
|
|||
}
|
||||
|
||||
|
||||
static int eapol_sm_confirm_auth(struct eapol_sm *sm)
|
||||
{
|
||||
if (!sm->ctx->confirm_auth_cb)
|
||||
return 0;
|
||||
|
||||
return sm->ctx->confirm_auth_cb(sm->ctx->ctx);
|
||||
}
|
||||
|
||||
|
||||
static void eapol_enable_timer_tick(struct eapol_sm *sm)
|
||||
{
|
||||
if (sm->timer_tick_enabled)
|
||||
|
@ -316,6 +325,11 @@ SM_STATE(SUPP_PAE, AUTHENTICATED)
|
|||
|
||||
SM_STATE(SUPP_PAE, RESTART)
|
||||
{
|
||||
if (eapol_sm_confirm_auth(sm)) {
|
||||
/* Don't process restart, we are already reconnecting */
|
||||
return;
|
||||
}
|
||||
|
||||
SM_ENTRY(SUPP_PAE, RESTART);
|
||||
sm->eapRestart = TRUE;
|
||||
if (sm->altAccept) {
|
||||
|
|
|
@ -298,6 +298,15 @@ struct eapol_ctx {
|
|||
* @len: Length of anonymous identity in octets
|
||||
*/
|
||||
void (*set_anon_id)(void *ctx, const u8 *id, size_t len);
|
||||
|
||||
/**
|
||||
* confirm_auth_cb - Callback confirming if we can install a new PTK
|
||||
* @ctx: eapol_ctx from eap_peer_sm_init() call
|
||||
* Returns: 0 when authentication can continue, -1 when reconnecting
|
||||
*
|
||||
* Automatically triggers a reconnect when not.
|
||||
*/
|
||||
int (*confirm_auth_cb)(void *ctx);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -183,6 +183,14 @@ void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise)
|
|||
int key_info, ver;
|
||||
u8 bssid[ETH_ALEN], *rbuf, *key_mic, *mic;
|
||||
|
||||
if (pairwise && sm->wpa_deny_ptk0_rekey &&
|
||||
wpa_sm_get_state(sm) == WPA_COMPLETED) {
|
||||
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
|
||||
"WPA: PTK0 rekey not allowed, reconnecting");
|
||||
wpa_sm_reconnect(sm);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wpa_use_akm_defined(sm->key_mgmt))
|
||||
ver = WPA_KEY_INFO_TYPE_AKM_DEFINED;
|
||||
else if (wpa_key_mgmt_ft(sm->key_mgmt) ||
|
||||
|
@ -618,6 +626,13 @@ static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
|
|||
return;
|
||||
}
|
||||
|
||||
if (sm->wpa_deny_ptk0_rekey && wpa_sm_get_state(sm) == WPA_COMPLETED) {
|
||||
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
|
||||
"WPA: PTK0 rekey not allowed, reconnecting");
|
||||
wpa_sm_reconnect(sm);
|
||||
return;
|
||||
}
|
||||
|
||||
wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
|
||||
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 1 of 4-Way "
|
||||
"Handshake from " MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
|
||||
|
@ -3142,6 +3157,9 @@ int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
|
|||
case WPA_PARAM_SAE_PWE:
|
||||
sm->sae_pwe = value;
|
||||
break;
|
||||
case WPA_PARAM_DENY_PTK0_REKEY:
|
||||
sm->wpa_deny_ptk0_rekey = value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ struct wpa_sm_ctx {
|
|||
void (*set_state)(void *ctx, enum wpa_states state);
|
||||
enum wpa_states (*get_state)(void *ctx);
|
||||
void (*deauthenticate)(void * ctx, u16 reason_code);
|
||||
void (*reconnect)(void *ctx);
|
||||
int (*set_key)(void *ctx, enum wpa_alg alg,
|
||||
const u8 *addr, int key_idx, int set_tx,
|
||||
const u8 *seq, size_t seq_len,
|
||||
|
@ -100,6 +101,7 @@ enum wpa_sm_conf_params {
|
|||
WPA_PARAM_MFP,
|
||||
WPA_PARAM_OCV,
|
||||
WPA_PARAM_SAE_PWE,
|
||||
WPA_PARAM_DENY_PTK0_REKEY,
|
||||
};
|
||||
|
||||
struct rsn_supp_config {
|
||||
|
@ -111,6 +113,7 @@ struct rsn_supp_config {
|
|||
const u8 *ssid;
|
||||
size_t ssid_len;
|
||||
int wpa_ptk_rekey;
|
||||
int wpa_deny_ptk0_rekey;
|
||||
int p2p;
|
||||
int wpa_rsc_relaxation;
|
||||
int owe_ptk_workaround;
|
||||
|
|
|
@ -63,6 +63,7 @@ struct wpa_sm {
|
|||
u8 ssid[32];
|
||||
size_t ssid_len;
|
||||
int wpa_ptk_rekey;
|
||||
int wpa_deny_ptk0_rekey:1;
|
||||
int p2p;
|
||||
int wpa_rsc_relaxation;
|
||||
int owe_ptk_workaround;
|
||||
|
@ -210,6 +211,12 @@ static inline int wpa_sm_set_key(struct wpa_sm *sm, enum wpa_alg alg,
|
|||
seq, seq_len, key, key_len, key_flag);
|
||||
}
|
||||
|
||||
static inline void wpa_sm_reconnect(struct wpa_sm *sm)
|
||||
{
|
||||
WPA_ASSERT(sm->ctx->reconnect);
|
||||
sm->ctx->reconnect(sm->ctx->ctx);
|
||||
}
|
||||
|
||||
static inline void * wpa_sm_get_network_ctx(struct wpa_sm *sm)
|
||||
{
|
||||
WPA_ASSERT(sm->ctx->get_network_ctx);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue