From 8b8d5ebfc9a13e8d8959f74f2198bb51bda7e359 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 29 Jul 2024 16:43:50 +0300 Subject: [PATCH] RSNO: Use SNonce cookie to indicate support for RSN overriding This provides an implicitly protected (SNonce is used as an input to PTK derivation) mechanism for a STA to indicate support for RSN overriding in a manner that does not cause interopability issues with deployed APs. In addition, update sm->SNonce on the Authenticator only based on message 2/4 since that is the only EAPOL-Key message that is defined to provide the actual SNonce value. While clearing of this internal buffer on message 4/4 might not cause issues, it is better to keep the actual SNonce value here since the SNonce cookie can be used at a later point in the sequence. Signed-off-by: Jouni Malinen --- components/wpa_supplicant/src/ap/wpa_auth.c | 10 ++++++++-- .../wpa_supplicant/src/common/wpa_common.c | 19 +++++++++++++++++++ .../wpa_supplicant/src/common/wpa_common.h | 3 +++ components/wpa_supplicant/src/rsn_supp/wpa.c | 3 ++- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/components/wpa_supplicant/src/ap/wpa_auth.c b/components/wpa_supplicant/src/ap/wpa_auth.c index e00fe390e00..61fca7457d2 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth.c +++ b/components/wpa_supplicant/src/ap/wpa_auth.c @@ -980,7 +980,8 @@ continue_processing: sm->EAPOLKeyReceived = TRUE; sm->EAPOLKeyPairwise = !!(key_info & WPA_KEY_INFO_KEY_TYPE); sm->EAPOLKeyRequest = !!(key_info & WPA_KEY_INFO_REQUEST); - memcpy(sm->SNonce, key->key_nonce, WPA_NONCE_LEN); + if (msg == PAIRWISE_2) + os_memcpy(sm->SNonce, key->key_nonce, WPA_NONCE_LEN); wpa_sm_step(sm); } @@ -1764,7 +1765,9 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) } /* Verify RSN Selection element for RSN overriding */ - if ((sm->rsn_selection && !kde.rsn_selection) || + if ((rsn_is_snonce_cookie(sm->SNonce) && !kde.rsn_selection) || + (!rsn_is_snonce_cookie(sm->SNonce) && kde.rsn_selection) || + (sm->rsn_selection && !kde.rsn_selection) || (!sm->rsn_selection && kde.rsn_selection) || (sm->rsn_selection && kde.rsn_selection && (sm->rsn_selection_len != kde.rsn_selection_len || @@ -1772,6 +1775,9 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) sm->rsn_selection_len) != 0))) { wpa_auth_logger(wpa_auth, wpa_auth_get_spa(sm), LOGGER_INFO, "RSN Selection element from (Re)AssocReq did not match the one in EAPOL-Key msg 2/4"); + wpa_printf(MSG_DEBUG, + "SNonce cookie for RSN overriding %sused", + rsn_is_snonce_cookie(sm->SNonce) ? "" : "not "); wpa_hexdump(MSG_DEBUG, "RSN Selection in AssocReq", sm->rsn_selection, sm->rsn_selection_len); wpa_hexdump(MSG_DEBUG, "RSN Selection in EAPOL-Key msg 2/4", diff --git a/components/wpa_supplicant/src/common/wpa_common.c b/components/wpa_supplicant/src/common/wpa_common.c index 388cad31c45..592840533c6 100644 --- a/components/wpa_supplicant/src/common/wpa_common.c +++ b/components/wpa_supplicant/src/common/wpa_common.c @@ -1722,4 +1722,23 @@ int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie) return ret; } +void rsn_set_snonce_cookie(u8 *snonce) +{ + u8 *pos; + + pos = snonce + WPA_NONCE_LEN - 6; + WPA_PUT_BE24(pos, OUI_WFA); + pos += 3; + WPA_PUT_BE24(pos, 0x000029); +} + + +bool rsn_is_snonce_cookie(const u8 *snonce) +{ + const u8 *pos; + + pos = snonce + WPA_NONCE_LEN - 6; + return WPA_GET_BE24(pos) == OUI_WFA && + WPA_GET_BE24(pos + 3) == 0x000029; +} #endif // ESP_SUPPLICANT diff --git a/components/wpa_supplicant/src/common/wpa_common.h b/components/wpa_supplicant/src/common/wpa_common.h index b7f8d0ca95f..d31c147227d 100644 --- a/components/wpa_supplicant/src/common/wpa_common.h +++ b/components/wpa_supplicant/src/common/wpa_common.h @@ -499,4 +499,7 @@ unsigned int wpa_mic_len(int akmp, size_t pmk_len); int wpa_use_akm_defined(int akmp); int wpa_use_aes_key_wrap(int akmp); +void rsn_set_snonce_cookie(u8 *snonce); +bool rsn_is_snonce_cookie(const u8 *snonce); + #endif /* WPA_COMMON_H */ diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index 40e5c9fcb3a..e4c86ae8878 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -733,7 +733,8 @@ void wpa_supplicant_process_1_of_4(struct wpa_sm *sm, wpa_printf(MSG_DEBUG, "WPA: Failed to get random data for SNonce"); goto failed; } - + if (sm->rsn_override != RSN_OVERRIDE_NOT_USED) + rsn_set_snonce_cookie(sm->snonce); sm->renew_snonce = 0; wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce", sm->snonce, WPA_NONCE_LEN);