Wireless Daemon for Linux
 help / color / mirror / Atom feed
From: James Prestwood <prestwoj@gmail.com>
To: iwd@lists.01.org
Subject: [PATCH v2 1/6] ft: create class for FT-over-DS targets
Date: Thu, 29 Apr 2021 12:40:58 -0700	[thread overview]
Message-ID: <20210429194103.207447-1-prestwoj@gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 5318 bytes --]

FT-over-DS is being separated into two independent stages. The
first of which is the processing of the action frame response.
This new class will hold all the parsed information from the action
frame and allowing it to be retrieved at a later time when IWD
needs to roam.

Initial info class should be created when the action frame is
being sent out. Once a response is received it can be parsed
with ft_over_ds_parse_action_response. This verifies the frame
and updates the ft_ds_info class with the parsed data.

ft_over_ds_prepare_handshake is the final step prior to
Reassociation. This sets all the stored IEs, anonce, and KH IDs
into the handshake and derives the new PTK.
---
 src/ft.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/ft.h |  25 +++++++++++++
 2 files changed, 131 insertions(+)

diff --git a/src/ft.c b/src/ft.c
index 85d2d369..82c790de 100644
--- a/src/ft.c
+++ b/src/ft.c
@@ -465,6 +465,52 @@ static bool ft_parse_fte(struct handshake_state *hs,
 	return true;
 }
 
+static bool ft_over_ds_process_ies(struct ft_ds_info *info,
+					struct handshake_state *hs,
+					const uint8_t *ies,
+					size_t ies_len)
+{
+	const uint8_t *rsne = NULL;
+	const uint8_t *mde = NULL;
+	const uint8_t *fte = NULL;
+	bool is_rsn;
+
+	if (ft_parse_ies(ies, ies_len, &rsne, &mde, &fte) < 0)
+		return false;
+
+	is_rsn = hs->supplicant_ie != NULL;
+
+	if (is_rsn) {
+		if (!ft_verify_rsne(rsne, hs->pmk_r0_name,
+					hs->authenticator_ie))
+			goto ft_error;
+	} else if (rsne)
+		goto ft_error;
+
+	/*
+	 * Check for an MD IE identical to the one we sent in message 1
+	 *
+	 * 12.8.3: "The MDE shall contain the MDID and FT Capability and
+	 * Policy fields. This element shall be the same as the MDE
+	 * advertised by the target AP in Beacon and Probe Response frames."
+	 */
+	if (!mde || memcmp(info->mde, mde + 2, sizeof(info->mde)))
+		goto ft_error;
+
+	if (is_rsn) {
+		if (!ft_parse_fte(hs, info->snonce, fte, &info->ft_info))
+			goto ft_error;
+
+		info->fte = l_memdup(fte, fte[1] + 2);
+	} else if (fte)
+		goto ft_error;
+
+	return true;
+
+ft_error:
+	return false;
+}
+
 static int ft_process_ies(struct handshake_state *hs, const uint8_t *ies,
 			size_t ies_len)
 {
@@ -523,6 +569,55 @@ ft_error:
 	return -EBADMSG;
 }
 
+int ft_over_ds_parse_action_response(struct ft_ds_info *info,
+					struct handshake_state *hs,
+					const uint8_t *frame, size_t frame_len)
+{
+	uint16_t status = 0;
+
+	if (frame_len < 16)
+		goto parse_error;
+
+	/* Category FT */
+	if (frame[0] != 6)
+		goto parse_error;
+
+	/* FT Action */
+	if (frame[1] != 2)
+		goto parse_error;
+
+	if (memcmp(frame + 2, info->spa, 6))
+		goto parse_error;
+	if (memcmp(frame + 8, info->aa, 6))
+		goto parse_error;
+
+	if (!ft_over_ds_process_ies(info, hs, frame + 16, frame_len - 16))
+		goto parse_error;
+
+	return 0;
+
+parse_error:
+	return (int)status;
+}
+
+bool ft_over_ds_prepare_handshake(struct ft_ds_info *info,
+					struct handshake_state *hs)
+{
+	memcpy(hs->snonce, info->snonce, sizeof(hs->snonce));
+
+	handshake_state_set_fte(hs, info->fte);
+
+	handshake_state_set_anonce(hs, info->ft_info.anonce);
+
+	handshake_state_set_kh_ids(hs, info->ft_info.r0khid,
+						info->ft_info.r0khid_len,
+						info->ft_info.r1khid);
+
+	handshake_state_derive_ptk(hs);
+
+	return true;
+}
+
 static int ft_rx_action(struct auth_proto *ap, const uint8_t *frame,
 				size_t frame_len)
 {
@@ -551,6 +646,17 @@ auth_error:
 	return (int)status_code;
 }
 
+void ft_ds_info_free(struct ft_ds_info *info)
+{
+	__typeof__(info->free) destroy = info->free;
+
+	if (info->fte)
+		l_free(info->fte);
+
+	if (destroy)
+		destroy(info);
+}
+
 static int ft_rx_authenticate(struct auth_proto *ap, const uint8_t *frame,
 				size_t frame_len)
 {
diff --git a/src/ft.h b/src/ft.h
index f24b3b5e..907c3d5d 100644
--- a/src/ft.h
+++ b/src/ft.h
@@ -20,15 +20,37 @@
  *
  */
 
+struct handshake_state;
+
 typedef void (*ft_tx_authenticate_func_t)(struct iovec *iov, size_t iov_len,
 					void *user_data);
 typedef void (*ft_tx_associate_func_t)(struct iovec *ie_iov, size_t iov_len,
 					void *user_data);
 
+typedef void (*ft_ds_free_func_t)(void *user_data);
+
+struct ft_ds_info {
+	uint8_t spa[6];
+	uint8_t aa[6];
+	uint8_t snonce[32];
+	uint8_t mde[3];
+	uint8_t *fte;
+
+	struct ie_ft_info ft_info;
+
+	void (*free)(struct ft_ds_info *s);
+};
+
+void ft_ds_info_free(struct ft_ds_info *info);
+
 bool ft_build_authenticate_ies(struct handshake_state *hs,
 				const uint8_t *new_snonce, uint8_t *buf,
 				size_t *len);
 
+int ft_over_ds_parse_action_response(struct ft_ds_info *info,
+					struct handshake_state *hs,
+					const uint8_t *frame, size_t frame_len);
+
 struct auth_proto *ft_over_air_sm_new(struct handshake_state *hs,
 				ft_tx_authenticate_func_t tx_auth,
 				ft_tx_associate_func_t tx_assoc,
@@ -38,3 +60,6 @@ struct auth_proto *ft_over_ds_sm_new(struct handshake_state *hs,
 				ft_tx_authenticate_func_t tx_auth,
 				ft_tx_associate_func_t tx_assoc,
 				void *user_data);
+
+bool ft_over_ds_prepare_handshake(struct ft_ds_info *info,
+					struct handshake_state *hs);
-- 
2.26.2

             reply	other threads:[~2021-04-29 19:40 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-29 19:40 James Prestwood [this message]
2021-04-29 19:40 ` [PATCH v2 2/6] ft: separate over-air from over-ds initializers James Prestwood
2021-04-29 19:41 ` [PATCH v2 3/6] netdev: separate over-air and over-ds netdev APIs James Prestwood
2021-04-29 19:41 ` [PATCH v2 4/6] ft: netdev: refactor FT-over-DS into two stages James Prestwood
2021-04-29 20:33   ` Denis Kenzior
2021-04-29 19:41 ` [PATCH v2 5/6] station: separate FT-over-DS stages James Prestwood
2021-04-29 19:41 ` [PATCH v2 6/6] ft: netdev: add return value to tx_associate James Prestwood
2021-04-29 20:23 ` [PATCH v2 1/6] ft: create class for FT-over-DS targets Denis Kenzior

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210429194103.207447-1-prestwoj@gmail.com \
    --to=prestwoj@gmail.com \
    --cc=iwd@lists.01.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox