]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
PASN: Calculate Auth1 hash after PTK derivation
authorJouni Malinen <jouni.malinen@oss.qualcomm.com>
Wed, 17 Dec 2025 20:06:14 +0000 (22:06 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 18 Dec 2025 10:08:24 +0000 (12:08 +0200)
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 <jouni.malinen@oss.qualcomm.com>
src/pasn/pasn_common.c
src/pasn/pasn_common.h
src/pasn/pasn_initiator.c
src/pasn/pasn_responder.c

index 7fc72a466200cacf3a7b9ec218807fd1baddbbda..ef8649b0842d2d91f7056bd6a0c98ba6e4e9dfb2 100644 (file)
@@ -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));
 }
 
index f6520630e6dd763c4d1c5503d44e05cfcb8733a0..578e7b12218cc7b5918a62b39f9161e05fff4eac 100644 (file)
@@ -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;
index d16ad62cd943d2a06210c24405530b783478ec3c..8882e4c66e93e0b59a7c6f0257e26c7f91f2f03e 100644 (file)
@@ -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;
 }
 
 
index aafbedf776520bb8af7ba5eb249fc91086dbd44e..64638145099b4e7e33cf3d8f0a76713a7f1d8c40 100644 (file)
@@ -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;