diff mbox series

[3/6] handshake: add handshake_state_pmkid_matches

Message ID 20230619225746.462791-3-prestwoj@gmail.com (mailing list archive)
State New
Headers show
Series [1/6] handshake: add force_sha1 flag to handshake_state_get_pmkid() | expand

Commit Message

James Prestwood June 19, 2023, 10:57 p.m. UTC
This will check if the given PMKID matches the derived PMKID. This
has been exposed as its own API in order to handle the case of the
PMKID being derived using the 'legacy' spec derivation, specifically
with the FT-8021X AKM. The spec was updated to be more clear on what
hash algorithm to use but older hostapd version use the old
derivation. This handles both and will allow EAPoL to accept the
PMKID in either case.
---
 src/handshake.c | 26 ++++++++++++++++++++++++++
 src/handshake.h |  3 ++-
 2 files changed, 28 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/src/handshake.c b/src/handshake.c
index bbab5ab6..7438c85a 100644
--- a/src/handshake.c
+++ b/src/handshake.c
@@ -767,6 +767,32 @@  bool handshake_state_get_pmkid(struct handshake_state *s, uint8_t *out_pmkid,
 					use_sha256);
 }
 
+bool handshake_state_pmkid_matches(struct handshake_state *s,
+					const uint8_t *check)
+{
+	uint8_t own_pmkid[16];
+
+	if (!handshake_state_get_pmkid(s, own_pmkid, false))
+		return false;
+
+	if (l_secure_memcmp(own_pmkid, check, 16)) {
+		if (s->akm_suite != IE_RSN_AKM_SUITE_FT_OVER_8021X)
+			return false;
+		/*
+		 * Recent hostapd versions (commit b6d3fd05e3) changed the PMKID
+		 * derivation for the FT-8021x AKM to use SHA256. This may be
+		 * the issue here so try the SHA1 derivation before giving up.
+		 */
+
+		if (!handshake_state_get_pmkid(s, own_pmkid, true))
+			return false;
+
+		return l_secure_memcmp(own_pmkid, check, 16) == 0;
+	}
+
+	return true;
+}
+
 void handshake_state_set_gtk(struct handshake_state *s, const uint8_t *key,
 				unsigned int key_index, const uint8_t *rsc)
 {
diff --git a/src/handshake.h b/src/handshake.h
index d9505593..3e3841bf 100644
--- a/src/handshake.h
+++ b/src/handshake.h
@@ -271,7 +271,8 @@  void handshake_state_override_pairwise_cipher(struct handshake_state *s,
 
 bool handshake_state_get_pmkid(struct handshake_state *s, uint8_t *out_pmkid,
 				bool force_sha1);
-
+bool handshake_state_pmkid_matches(struct handshake_state *s,
+					const uint8_t *check);
 bool handshake_decode_fte_key(struct handshake_state *s, const uint8_t *wrapped,
 				size_t key_len, uint8_t *key_out);