From: Jouni Malinen Date: Wed, 17 Dec 2025 20:06:14 +0000 (+0200) Subject: PASN: Calculate Auth1 hash after PTK derivation X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5e5aba3dc8c5b3d8dd797c3b7d4d019b89b773f0;p=thirdparty%2Fhostap.git PASN: Calculate Auth1 hash after PTK derivation It is more convenient to wait with the Auth1 hash calculation to avoid having to figure out which hash algorithm to use before the PTK is derived. Auth1 hash is defined to use the same hash algorithm as the one that was used during PTK derivation. This requires a bit more memory, but that is justifiable with the simplified implementation. Signed-off-by: Jouni Malinen --- diff --git a/src/pasn/pasn_common.c b/src/pasn/pasn_common.c index 7fc72a466..ef8649b08 100644 --- a/src/pasn/pasn_common.c +++ b/src/pasn/pasn_common.c @@ -35,6 +35,7 @@ void pasn_data_deinit(struct pasn_data *pasn) os_free(pasn->rsnxe_ie); wpabuf_free(pasn->frame); os_free(pasn->pasn_groups); + wpabuf_free(pasn->auth1); bin_clear_free(pasn, sizeof(struct pasn_data)); } diff --git a/src/pasn/pasn_common.h b/src/pasn/pasn_common.h index f6520630e..578e7b122 100644 --- a/src/pasn/pasn_common.h +++ b/src/pasn/pasn_common.h @@ -16,7 +16,6 @@ #ifdef CONFIG_SAE #include "common/sae.h" #endif /* CONFIG_SAE */ -#include "crypto/sha384.h" #ifdef __cplusplus extern "C" { @@ -86,7 +85,7 @@ struct pasn_data { bool using_pmksa; enum rsn_hash_alg hash_alg; - u8 hash[SHA384_MAC_LEN]; + struct wpabuf *auth1; struct wpabuf *beacon_rsne_rsnxe; struct wpa_ptk ptk; diff --git a/src/pasn/pasn_initiator.c b/src/pasn/pasn_initiator.c index d16ad62cd..8882e4c66 100644 --- a/src/pasn/pasn_initiator.c +++ b/src/pasn/pasn_initiator.c @@ -17,6 +17,7 @@ #include "common/ieee802_11_defs.h" #include "common/dragonfly.h" #include "crypto/sha384.h" +#include "crypto/sha512.h" #include "crypto/crypto.h" #include "crypto/random.h" #include "eap_common/eap_defs.h" @@ -588,7 +589,6 @@ static struct wpabuf * wpas_pasn_build_auth_1(struct pasn_data *pasn, struct wpabuf *buf, *pubkey = NULL, *wrapped_data_buf = NULL; const u8 *pmkid; u8 wrapped_data; - int ret; wpa_printf(MSG_DEBUG, "PASN: Building frame 1"); @@ -657,12 +657,11 @@ static struct wpabuf * wpas_pasn_build_auth_1(struct pasn_data *pasn, wpa_pasn_add_extra_ies(buf, pasn->extra_ies, pasn->extra_ies_len); - ret = pasn_auth_frame_hash(pasn->akmp, pasn->cipher, - wpabuf_head_u8(buf) + IEEE80211_HDRLEN, - wpabuf_len(buf) - IEEE80211_HDRLEN, - pasn->hash); - if (ret) { - wpa_printf(MSG_DEBUG, "PASN: Failed to compute hash"); + wpabuf_free(pasn->auth1); + pasn->auth1 = wpabuf_alloc_copy(wpabuf_head_u8(buf) + IEEE80211_HDRLEN, + wpabuf_len(buf) - IEEE80211_HDRLEN); + if (!pasn->auth1) { + wpa_printf(MSG_DEBUG, "PASN: Failed to store a copy of Auth1"); goto fail; } @@ -692,6 +691,7 @@ static struct wpabuf * wpas_pasn_build_auth_3(struct pasn_data *pasn) u8 *ptr; u8 wrapped_data; int ret; + u8 hash[SHA512_MAC_LEN]; wpa_printf(MSG_DEBUG, "PASN: Building frame 3"); @@ -738,9 +738,17 @@ static struct wpabuf * wpas_pasn_build_auth_3(struct pasn_data *pasn) data = wpabuf_head_u8(buf) + IEEE80211_HDRLEN; data_len = wpabuf_len(buf) - IEEE80211_HDRLEN; + if (!pasn->auth1 || + pasn_auth_frame_hash(pasn->akmp, pasn->cipher, + wpabuf_head(pasn->auth1), + wpabuf_len(pasn->auth1), hash)) { + wpa_printf(MSG_INFO, "PASN: Failed to calculate Auth1 hash"); + goto fail; + } + ret = pasn_mic(pasn->ptk.kck, pasn->akmp, pasn->cipher, pasn->own_addr, pasn->peer_addr, - pasn->hash, mic_len * 2, data, data_len, mic); + hash, mic_len * 2, data, data_len, mic); if (ret) { wpa_printf(MSG_DEBUG, "PASN: frame 3: Failed MIC calculation"); goto fail; @@ -784,7 +792,9 @@ void wpa_pasn_reset(struct pasn_data *pasn) forced_memzero(pasn->pmk, sizeof(pasn->pmk)); forced_memzero(&pasn->ptk, sizeof(pasn->ptk)); - forced_memzero(&pasn->hash, sizeof(pasn->hash)); + + wpabuf_free(pasn->auth1); + pasn->auth1 = NULL; wpabuf_free(pasn->beacon_rsne_rsnxe); pasn->beacon_rsne_rsnxe = NULL; @@ -831,6 +841,9 @@ void wpa_pasn_reset(struct pasn_data *pasn) wpabuf_free(pasn->frame); pasn->frame = NULL; + + wpabuf_free(pasn->auth1); + pasn->auth1 = NULL; } diff --git a/src/pasn/pasn_responder.c b/src/pasn/pasn_responder.c index aafbedf77..646381450 100644 --- a/src/pasn/pasn_responder.c +++ b/src/pasn/pasn_responder.c @@ -17,6 +17,7 @@ #include "common/ieee802_11_defs.h" #include "crypto/sha384.h" #include "crypto/sha256.h" +#include "crypto/sha512.h" #include "crypto/random.h" #include "crypto/crypto.h" #include "ap/hostapd.h" @@ -898,11 +899,11 @@ int handle_auth_pasn_1(struct pasn_data *pasn, pasn->wrapped_data_format = pasn_params.wrapped_data_format; - ret = pasn_auth_frame_hash(pasn->akmp, pasn->cipher, - ((const u8 *) mgmt) + IEEE80211_HDRLEN, - len - IEEE80211_HDRLEN, pasn->hash); - if (ret) { - wpa_printf(MSG_DEBUG, "PASN: Failed to compute hash"); + wpabuf_free(pasn->auth1); + pasn->auth1 = wpabuf_alloc_copy(((const u8 *) mgmt) + IEEE80211_HDRLEN, + len - IEEE80211_HDRLEN); + if (!pasn->auth1) { + wpa_printf(MSG_DEBUG, "PASN: Failed to store a copy of Auth1"); status = WLAN_STATUS_UNSPECIFIED_FAILURE; goto send_resp; } @@ -974,11 +975,11 @@ int handle_auth_pasn_1(struct pasn_data *pasn, goto send_resp; } - ret = pasn_auth_frame_hash(pasn->akmp, pasn->cipher, - ((const u8 *) mgmt) + IEEE80211_HDRLEN, - len - IEEE80211_HDRLEN, pasn->hash); - if (ret) { - wpa_printf(MSG_DEBUG, "PASN: Failed to compute hash"); + wpabuf_free(pasn->auth1); + pasn->auth1 = wpabuf_alloc_copy(((const u8 *) mgmt) + IEEE80211_HDRLEN, + len - IEEE80211_HDRLEN); + if (!pasn->auth1) { + wpa_printf(MSG_DEBUG, "PASN: Failed to store a copy of Auth1"); status = WLAN_STATUS_UNSPECIFIED_FAILURE; } @@ -1014,6 +1015,7 @@ int handle_auth_pasn_3(struct pasn_data *pasn, const u8 *own_addr, int ret; u8 *copy = NULL; size_t copy_len, mic_offset; + u8 hash[SHA512_MAC_LEN]; if (ieee802_11_parse_elems(mgmt->u.auth.variable, len - offsetof(struct ieee80211_mgmt, @@ -1064,9 +1066,16 @@ int handle_auth_pasn_3(struct pasn_data *pasn, const u8 *own_addr, if (!copy) goto fail; os_memset(copy + mic_offset, 0, mic_len); + if (!pasn->auth1 || + pasn_auth_frame_hash(pasn->akmp, pasn->cipher, + wpabuf_head(pasn->auth1), + wpabuf_len(pasn->auth1), hash)) { + wpa_printf(MSG_INFO, "PASN: Failed to calculate Auth1 hash"); + goto fail; + } ret = pasn_mic(pasn->ptk.kck, pasn->akmp, pasn->cipher, peer_addr, own_addr, - pasn->hash, mic_len * 2, + hash, mic_len * 2, copy, copy_len, out_mic); os_free(copy); copy = NULL;