From: Ben Greear <greearb@xxxxxxxxxxxxxxx> Good for testing the peer's state machine logic. Signed-off-by: Ben Greear <greearb@xxxxxxxxxxxxxxx> --- src/rsn_supp/peerkey.c | 10 ++++---- src/rsn_supp/wpa.c | 50 ++++++++++++++++++++++++++++++++++---- src/rsn_supp/wpa.h | 23 ++++++++++++++++-- src/rsn_supp/wpa_i.h | 7 +++++- wpa_supplicant/config.c | 9 +++++++ wpa_supplicant/config.h | 6 +++++ wpa_supplicant/wpa_supplicant.c | 1 - wpa_supplicant/wpa_supplicant.conf | 6 +++++ wpa_supplicant/wpas_glue.c | 9 +++++++ 9 files changed, 107 insertions(+), 14 deletions(-) diff --git a/src/rsn_supp/peerkey.c b/src/rsn_supp/peerkey.c index ce338f8..f674213 100644 --- a/src/rsn_supp/peerkey.c +++ b/src/rsn_supp/peerkey.c @@ -114,7 +114,7 @@ static int wpa_supplicant_send_smk_error(struct wpa_sm *sm, const u8 *dst, } wpa_eapol_key_send(sm, &sm->ptk, ver, dst, ETH_P_EAPOL, rbuf, rlen, - mic); + mic, EAPOL_MSG_TYPE_SMK_ERROR); return 0; } @@ -167,7 +167,7 @@ static int wpa_supplicant_send_smk_m3(struct wpa_sm *sm, wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key SMK M3"); wpa_eapol_key_send(sm, &sm->ptk, ver, src_addr, ETH_P_EAPOL, rbuf, rlen, - mic); + mic, EAPOL_MSG_TYPE_SMK_M3); return 0; } @@ -371,7 +371,7 @@ static void wpa_supplicant_send_stk_1_of_4(struct wpa_sm *sm, wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 1/4 to " MACSTR, MAC2STR(peerkey->addr)); wpa_eapol_key_send(sm, NULL, ver, peerkey->addr, ETH_P_EAPOL, - mbuf, mlen, NULL); + mbuf, mlen, NULL, EAPOL_MSG_TYPE_STK_1_OF_4); } @@ -427,7 +427,7 @@ static void wpa_supplicant_send_stk_3_of_4(struct wpa_sm *sm, wpa_printf(MSG_DEBUG, "RSN: Sending EAPOL-Key STK 3/4 to " MACSTR, MAC2STR(peerkey->addr)); wpa_eapol_key_send(sm, &peerkey->stk, ver, peerkey->addr, ETH_P_EAPOL, - mbuf, mlen, mic); + mbuf, mlen, mic, EAPOL_MSG_TYPE_STK_3_OF_4); } @@ -1094,7 +1094,7 @@ int wpa_sm_stkstart(struct wpa_sm *sm, const u8 *peer) wpa_printf(MSG_INFO, "RSN: Sending EAPOL-Key SMK M1 Request (peer " MACSTR ")", MAC2STR(peer)); wpa_eapol_key_send(sm, &sm->ptk, ver, bssid, ETH_P_EAPOL, rbuf, rlen, - mic); + mic, EAPOL_MSG_TYPE_SMK_M1); peerkey->next = sm->peerkey; sm->peerkey = peerkey; diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 4d68998..ccd7f30 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -29,6 +29,27 @@ static const u8 null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +#ifdef CONFIG_TESTING_OPTIONS +const char* eapol_msg_type_str(enum eapol_key_msg_type t) +{ + static const char* types_str[EAPOL_MSG_TYPE_MAX] = + {"UNKNOWN", "1/4", "2/4", "3/4", "4/4", "1/2", "2/2", "KEY-REQ", + "SMK-ERROR", "SMK-M1", "SMK-M3", "STK-1/4", "STK-3/4" }; + if (t >= 0 && t < EAPOL_MSG_TYPE_MAX) + return types_str[t]; + return types_str[EAPOL_MSG_TYPE_UNKNOWN]; +} + +void wpa_apply_corruptions(struct wpa_sm *sm, u16 corrupt_eapol_2_of_4, + u16 corrupt_eapol_4_of_4, u16 corrupt_eapol_2_of_2, + u16 corrupt_eapol_key_req) +{ + sm->corrupt_eapol_2_of_4 = corrupt_eapol_2_of_4; + sm->corrupt_eapol_4_of_4 = corrupt_eapol_4_of_4; + sm->corrupt_eapol_2_of_2 = corrupt_eapol_2_of_2; + sm->corrupt_eapol_key_req = corrupt_eapol_key_req; +} +#endif /** * wpa_eapol_key_send - Send WPA/RSN EAPOL-Key message @@ -44,7 +65,8 @@ static const u8 null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; */ int wpa_eapol_key_send(struct wpa_sm *sm, struct wpa_ptk *ptk, 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, + enum eapol_key_msg_type eapol_type) { int ret = -1; size_t mic_len = wpa_mic_len(sm->key_mgmt); @@ -149,6 +171,24 @@ int wpa_eapol_key_send(struct wpa_sm *sm, struct wpa_ptk *ptk, #endif /* CONFIG_FILS */ } +#ifdef CONFIG_TESTING_OPTIONS + /* Purposefully corrupt the frame for testing purposes? */ + if (((sm->corrupt_eapol_2_of_4 && eapol_type == EAPOL_MSG_TYPE_2_OF_4) && + (os_random() % 65535) < sm->corrupt_eapol_2_of_4) || + ((sm->corrupt_eapol_4_of_4 && eapol_type == EAPOL_MSG_TYPE_4_OF_4) && + (os_random() % 65535) < sm->corrupt_eapol_4_of_4) || + ((sm->corrupt_eapol_key_req && eapol_type == EAPOL_MSG_TYPE_KEY_REQUEST) && + (os_random() % 65535) < sm->corrupt_eapol_key_req) || + ((sm->corrupt_eapol_2_of_2 && eapol_type == EAPOL_MSG_TYPE_GROUP_2_OF_2) && + (os_random() % 65535) < sm->corrupt_eapol_2_of_2)) { + /* Corrupt a random byte, maybe more?? */ + int idx = os_random() % msg_len; + msg[idx] = os_random(); + wpa_msg(sm->ctx->msg_ctx, MSG_INFO, + "WPA: Corrupting EAPOL message type: %s, idx: %d value: 0x%x\n", + eapol_msg_type_str(eapol_type), idx, msg[idx]); + } +#endif wpa_hexdump(MSG_MSGDUMP, "WPA: TX EAPOL-Key", msg, msg_len); ret = wpa_sm_ether_send(sm, dest, proto, msg, msg_len); eapol_sm_notify_tx_eapol_key(sm->eapol); @@ -229,7 +269,7 @@ void wpa_sm_key_request(struct wpa_sm *sm, int error, int pairwise) "pairwise=%d ptk_set=%d len=%lu)", error, pairwise, sm->ptk_set, (unsigned long) rlen); wpa_eapol_key_send(sm, &sm->ptk, ver, bssid, ETH_P_EAPOL, rbuf, rlen, - key_mic); + key_mic, EAPOL_MSG_TYPE_KEY_REQUEST); } @@ -493,7 +533,7 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst, wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/4"); return wpa_eapol_key_send(sm, ptk, ver, dst, ETH_P_EAPOL, rbuf, rlen, - key_mic); + key_mic, EAPOL_MSG_TYPE_2_OF_4); } @@ -1249,7 +1289,7 @@ int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst, wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 4/4"); return wpa_eapol_key_send(sm, ptk, ver, dst, ETH_P_EAPOL, rbuf, rlen, - key_mic); + key_mic, EAPOL_MSG_TYPE_4_OF_4); } @@ -1555,7 +1595,7 @@ static int wpa_supplicant_send_2_of_2(struct wpa_sm *sm, wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 2/2"); return wpa_eapol_key_send(sm, &sm->ptk, ver, sm->bssid, ETH_P_EAPOL, - rbuf, rlen, key_mic); + rbuf, rlen, key_mic, EAPOL_MSG_TYPE_GROUP_2_OF_2); } diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index 29b2f33..c1009f3 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -117,6 +117,13 @@ enum eapol_key_msg_type { EAPOL_MSG_TYPE_4_OF_4, /* sent by sta */ EAPOL_MSG_TYPE_GROUP_1_OF_2, /* rx by sta */ EAPOL_MSG_TYPE_GROUP_2_OF_2, /* sent by sta */ + EAPOL_MSG_TYPE_KEY_REQUEST, + EAPOL_MSG_TYPE_SMK_ERROR, + EAPOL_MSG_TYPE_SMK_M1, + EAPOL_MSG_TYPE_SMK_M3, + EAPOL_MSG_TYPE_STK_1_OF_4, + EAPOL_MSG_TYPE_STK_3_OF_4, + EAPOL_MSG_TYPE_MAX, }; @@ -124,6 +131,10 @@ enum eapol_key_msg_type { #ifdef CONFIG_TESTING_OPTIONS enum eapol_key_msg_type wpa_eapol_key_type(struct wpa_sm *sm, const u8 *buf, size_t len); +const char* eapol_msg_type_str(enum eapol_key_msg_type t); +void wpa_apply_corruptions(struct wpa_sm* wpa_sm, u16 corrupt_eapol_2_of_4, + u16 corrupt_eapol_4_of_4, u16 corrupt_eapol_2_of_2, + u16 corrupt_eapol_key_req); #endif @@ -186,10 +197,18 @@ void wpa_sm_set_ptk_kck_kek(struct wpa_sm *sm, #else /* CONFIG_NO_WPA */ #ifdef CONFIG_TESTING_OPTIONS -enum eapol_key_msg_type wpa_eapol_key_type(struct wpa_sm *sm, const u8 *src_addr, - const u8 *buf, size_t len) { +static inline enum eapol_key_msg_type +wpa_eapol_key_type(struct wpa_sm *sm, const u8 *src_addr, + const u8 *buf, size_t len) +{ return EAPOL_MSG_TYPE_UNKNOWN; } + +static inline void wpa_apply_corruptions(struct wpa_sm *sm, u16 corrupt_eapol_2_of_4, + u16 corrupt_eapol_4_of_4, u16 corrupt_eapol_2_of_2, + u16 corrupt_eapol_key_req) +{ +} #endif static inline struct wpa_sm * wpa_sm_init(struct wpa_sm_ctx *ctx) diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index 180d468..61662fb 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -137,6 +137,11 @@ struct wpa_sm { #ifdef CONFIG_TESTING_OPTIONS struct wpabuf *test_assoc_ie; + + u16 corrupt_eapol_2_of_4; + u16 corrupt_eapol_4_of_4; + u16 corrupt_eapol_2_of_2; + u16 corrupt_eapol_key_req; #endif /* CONFIG_TESTING_OPTIONS */ #ifdef CONFIG_FILS @@ -365,7 +370,7 @@ static inline int wpa_sm_key_mgmt_set_pmk(struct wpa_sm *sm, int wpa_eapol_key_send(struct wpa_sm *sm, struct wpa_ptk *ptk, 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, enum eapol_key_msg_type eapol_type); int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst, const struct wpa_eapol_key *key, int ver, const u8 *nonce, diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 2bff8e7..d56b6da 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -3838,6 +3838,11 @@ struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface, config->ignore_eapol_1_of_4 = DEFAULT_IGNORE_AUTH_RESP; config->ignore_eapol_3_of_4 = DEFAULT_IGNORE_AUTH_RESP; config->ignore_eapol_1_of_2 = DEFAULT_IGNORE_AUTH_RESP; + + config->corrupt_eapol_2_of_4 = DEFAULT_IGNORE_AUTH_RESP; + config->corrupt_eapol_4_of_4 = DEFAULT_IGNORE_AUTH_RESP; + config->corrupt_eapol_2_of_2 = DEFAULT_IGNORE_AUTH_RESP; + config->corrupt_eapol_key_req = DEFAULT_IGNORE_AUTH_RESP; #endif return config; @@ -4563,6 +4568,10 @@ static const struct global_parse_data global_fields[] = { { INT(ignore_eapol_1_of_4), 0 }, { INT(ignore_eapol_3_of_4), 0 }, { INT(ignore_eapol_1_of_2), 0 }, + { INT(corrupt_eapol_2_of_4), 0 }, + { INT(corrupt_eapol_4_of_4), 0 }, + { INT(corrupt_eapol_2_of_2), 0 }, + { INT(corrupt_eapol_key_req), 0 }, #endif { INT(accept_external_scan_results), 0 }, { STR(wowlan_triggers), 0 }, diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index f93ca78..1e31255 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -891,6 +891,12 @@ struct wpa_config { unsigned short ignore_eapol_1_of_4; unsigned short ignore_eapol_3_of_4; unsigned short ignore_eapol_1_of_2; + + unsigned short corrupt_eapol_2_of_4; + unsigned short corrupt_eapol_4_of_4; + unsigned short corrupt_eapol_2_of_2; + unsigned short corrupt_eapol_key_req; + #endif /** diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 52a986a..7c2ebd3 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -3516,7 +3516,6 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, return; } - /* Check for dropping specific eapol frames */ emt = wpa_eapol_key_type(wpa_s->wpa, buf, len); if (emt == EAPOL_MSG_TYPE_1_OF_4) { diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf index 27985a3..500d575 100644 --- a/wpa_supplicant/wpa_supplicant.conf +++ b/wpa_supplicant/wpa_supplicant.conf @@ -1379,6 +1379,12 @@ fast_reauth=1 #ignore_eapol_3_of_4=1000 #ignore_eapol_1_of_2=1000 +# Randomly set a byte in the message to a different value +#corrupt_eapol_2_of_4=1000 +#corrupt_eapol_4_of_4=1000 +#corrupt_eapol_2_of_2=1000 +#corrupt_eapol_key_req=1000 + # Example blocks: diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c index 16ffc7f..06de244 100644 --- a/wpa_supplicant/wpas_glue.c +++ b/wpa_supplicant/wpas_glue.c @@ -1170,6 +1170,15 @@ int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s) os_free(ctx); return -1; } + +#ifdef CONFIG_TESTING_OPTIONS + wpa_apply_corruptions(wpa_s->wpa, + wpa_s->conf->corrupt_eapol_2_of_4, + wpa_s->conf->corrupt_eapol_4_of_4, + wpa_s->conf->corrupt_eapol_2_of_2, + wpa_s->conf->corrupt_eapol_key_req); +#endif + #endif /* CONFIG_NO_WPA */ return 0; -- 1.9.3 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap