diff mbox series

[7/8] eapol: allow 'secure' to be set on rekeys

Message ID 20220624230741.1957863-7-prestwoj@gmail.com (mailing list archive)
State Accepted, archived
Headers show
Series [1/8] test-runner: remove reference to missing class member | expand

Commit Message

James Prestwood June 24, 2022, 11:07 p.m. UTC
About a month ago hostapd was changed to set the secure bit on
eapol frames during rekeys (bc36991791). The spec is ambiguous
about this and has conflicting info depending on the sections you
read (12.7.2 vs 12.7.6). According to the hostapd commit log TGme
is trying to clarify this and wants to set secure=1 in the case
of rekeys. Because of this, IWD is completely broken with rekeys
since its disallows secure=1 on PTK 1/4 and 2/4.

Now, a bool is passed to the verify functions which signifies if
the PTK has been negotiated already. If secure differs from this
the key frame is not verified.
---
 src/eapol.c | 14 ++++++++------
 src/eapol.h |  5 +++--
 2 files changed, 11 insertions(+), 8 deletions(-)
diff mbox series

Patch

diff --git a/src/eapol.c b/src/eapol.c
index 9f885d02..e8bd5cdb 100644
--- a/src/eapol.c
+++ b/src/eapol.c
@@ -443,7 +443,8 @@  static void eapol_key_data_append(struct eapol_key *ek,
 	if (ek->error)		\
 		return false	\
 
-bool eapol_verify_ptk_1_of_4(const struct eapol_key *ek, size_t mic_len)
+bool eapol_verify_ptk_1_of_4(const struct eapol_key *ek, size_t mic_len,
+				bool ptk_complete)
 {
 	/* Verify according to 802.11, Section 11.6.6.2 */
 	VERIFY_PTK_COMMON(ek);
@@ -457,7 +458,7 @@  bool eapol_verify_ptk_1_of_4(const struct eapol_key *ek, size_t mic_len)
 	if (ek->key_mic)
 		return false;
 
-	if (ek->secure)
+	if (ek->secure != ptk_complete)
 		return false;
 
 	if (ek->encrypted_key_data)
@@ -475,7 +476,7 @@  bool eapol_verify_ptk_1_of_4(const struct eapol_key *ek, size_t mic_len)
 	return true;
 }
 
-bool eapol_verify_ptk_2_of_4(const struct eapol_key *ek)
+bool eapol_verify_ptk_2_of_4(const struct eapol_key *ek, bool ptk_complete)
 {
 	uint16_t key_len;
 
@@ -491,7 +492,7 @@  bool eapol_verify_ptk_2_of_4(const struct eapol_key *ek)
 	if (!ek->key_mic)
 		return false;
 
-	if (ek->secure)
+	if (ek->secure != ptk_complete)
 		return false;
 
 	if (ek->encrypted_key_data)
@@ -1151,7 +1152,8 @@  static void eapol_handle_ptk_1_of_4(struct eapol_sm *sm,
 
 	l_debug("ifindex=%u", sm->handshake->ifindex);
 
-	if (!eapol_verify_ptk_1_of_4(ek, sm->mic_len))
+	if (!eapol_verify_ptk_1_of_4(ek, sm->mic_len,
+					sm->handshake->ptk_complete))
 		return;
 
 	if (sm->handshake->ptk_complete && unencrypted) {
@@ -1523,7 +1525,7 @@  static void eapol_handle_ptk_2_of_4(struct eapol_sm *sm,
 
 	l_debug("ifindex=%u", sm->handshake->ifindex);
 
-	if (!eapol_verify_ptk_2_of_4(ek))
+	if (!eapol_verify_ptk_2_of_4(ek, sm->handshake->ptk_complete))
 		return;
 
 	if (L_BE64_TO_CPU(ek->key_replay_counter) != sm->replay_counter)
diff --git a/src/eapol.h b/src/eapol.h
index 53ae6e8f..8d8d5252 100644
--- a/src/eapol.h
+++ b/src/eapol.h
@@ -65,8 +65,9 @@  uint8_t *eapol_decrypt_key_data(enum ie_rsn_akm_suite akm, const uint8_t *kek,
 				const struct eapol_key *frame,
 				size_t *decrypted_size, size_t mic_len);
 
-bool eapol_verify_ptk_1_of_4(const struct eapol_key *ek, size_t mic_len);
-bool eapol_verify_ptk_2_of_4(const struct eapol_key *ek);
+bool eapol_verify_ptk_1_of_4(const struct eapol_key *ek, size_t mic_len,
+				bool ptk_complete);
+bool eapol_verify_ptk_2_of_4(const struct eapol_key *ek, bool ptk_complete);
 bool eapol_verify_ptk_3_of_4(const struct eapol_key *ek, bool is_wpa,
 				size_t mic_len);
 bool eapol_verify_ptk_4_of_4(const struct eapol_key *ek, bool is_wpa);