* [PATCH v3 1/3] eapol: implement rekey support for authenticator
@ 2023-01-18 21:17 James Prestwood
2023-01-18 21:18 ` [PATCH v3 2/3] ap: support PTK rekeys James Prestwood
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: James Prestwood @ 2023-01-18 21:17 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
The only changes required was to set the secure bit for message 1,
reset the frame retry counter, and change the 2/4 verifier to use
the rekey flag rather than ptk_complete. This is because we must
set ptk_complete false in order to detect retransmissions of the
4/4 frame.
Initiating a rekey can now be done by simply calling eapol_start().
---
src/eapol.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
v3:
* Set ek->secure to sm->rekey always to ensure retransmissions get
the secure bit set.
diff --git a/src/eapol.c b/src/eapol.c
index c7128aeb..26974848 100644
--- a/src/eapol.c
+++ b/src/eapol.c
@@ -1086,8 +1086,6 @@ static void eapol_send_ptk_1_of_4(struct eapol_sm *sm)
handshake_state_new_anonce(sm->handshake);
- sm->handshake->ptk_complete = false;
-
sm->replay_counter++;
memset(ek, 0, EAPOL_FRAME_LEN(sm->mic_len));
@@ -1111,6 +1109,13 @@ static void eapol_send_ptk_1_of_4(struct eapol_sm *sm)
eapol_key_data_append(ek, sm->mic_len, HANDSHAKE_KDE_PMKID, pmkid, 16);
+ if (sm->handshake->ptk_complete) {
+ sm->rekey = true;
+ sm->handshake->ptk_complete = false;
+ }
+
+ ek->secure = sm->rekey;
+
ek->header.packet_len = L_CPU_TO_BE16(EAPOL_FRAME_LEN(sm->mic_len) +
EAPOL_KEY_DATA_LEN(ek, sm->mic_len) - 4);
@@ -1589,7 +1594,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, sm->handshake->ptk_complete))
+ if (!eapol_verify_ptk_2_of_4(ek, sm->rekey))
return;
if (L_BE64_TO_CPU(ek->key_replay_counter) != sm->replay_counter)
@@ -2488,6 +2493,8 @@ static void eapol_eap_complete_cb(enum eap_result result, void *user_data)
/* sm->mic_len will have been set in eapol_eap_results_cb */
+ sm->frame_retry = 0;
+
/* Kick off 4-Way Handshake */
eapol_ptk_1_of_4_retry(NULL, sm);
}
@@ -2879,6 +2886,8 @@ bool eapol_start(struct eapol_sm *sm)
if (L_WARN_ON(!sm->handshake->have_pmk))
return false;
+ sm->frame_retry = 0;
+
/* Kick off handshake */
eapol_ptk_1_of_4_retry(NULL, sm);
}
--
2.34.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v3 2/3] ap: support PTK rekeys
2023-01-18 21:17 [PATCH v3 1/3] eapol: implement rekey support for authenticator James Prestwood
@ 2023-01-18 21:18 ` James Prestwood
2023-01-18 21:18 ` [PATCH v3 3/3] doc: Document RekeyTimeout for AP profiles James Prestwood
2023-01-18 21:42 ` [PATCH v3 1/3] eapol: implement rekey support for authenticator Denis Kenzior
2 siblings, 0 replies; 4+ messages in thread
From: James Prestwood @ 2023-01-18 21:18 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
This adds support for rekeys to AP mode. A single timer is used and
reset to the next station needing a rekey. A default rekey timer of
600 seconds is used unless the profile sets a timeout.
---
src/ap.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 116 insertions(+)
v3:
* Rename API to ap_check_rekeys. As this both starts rekeys and
resets the timer
* Use l_timeout_modify when the timer is reset to a new station
* Check sta->rekey_time as well as set to 0 in case of del station.
This ensures the station that left isn't taken into account when
the rekey timeout is calculated.
* Make the default rekey time zero (disabled) if no config value is
set.
diff --git a/src/ap.c b/src/ap.c
index 1d937103..531babb2 100644
--- a/src/ap.c
+++ b/src/ap.c
@@ -106,6 +106,9 @@ struct ap_state {
struct l_dbus_message *scan_pending;
struct l_queue *networks;
+ struct l_timeout *rekey_timeout;
+ unsigned int rekey_time;
+
bool started : 1;
bool gtk_set : 1;
bool netconfig_set_addr4 : 1;
@@ -137,6 +140,7 @@ struct sta_state {
bool wsc_v2;
struct l_dhcp_lease *ip_alloc_lease;
bool ip_alloc_sent;
+ uint64_t rekey_time;
bool ht_support : 1;
bool ht_greenfield : 1;
@@ -345,6 +349,11 @@ static void ap_reset(struct ap_state *ap)
l_queue_destroy(ap->networks, l_free);
ap->networks = NULL;
}
+
+ if (ap->rekey_timeout) {
+ l_timeout_remove(ap->rekey_timeout);
+ ap->rekey_timeout = NULL;
+ }
}
static bool ap_event_done(struct ap_state *ap, bool prev_in_event)
@@ -377,6 +386,8 @@ static bool ap_event(struct ap_state *ap, enum ap_event_type event,
return ap_event_done(ap, prev);
}
+static void ap_check_rekeys(struct ap_state *ap);
+
static void ap_del_station(struct sta_state *sta, uint16_t reason,
bool disassociate)
{
@@ -439,6 +450,93 @@ static void ap_del_station(struct sta_state *sta, uint16_t reason,
ap_event_done(ap, prev);
}
+
+ /*
+ * Set the rekey time to zero which will skip this station when
+ * determining the next rekey.
+ */
+ sta->rekey_time = 0;
+ ap_check_rekeys(ap);
+}
+
+static void ap_start_rekey(struct ap_state *ap, struct sta_state *sta)
+{
+ l_debug("Rekey STA "MAC, MAC_STR(sta->addr));
+
+ eapol_start(sta->sm);
+}
+
+static void ap_rekey_timeout(struct l_timeout *timeout, void *user_data)
+{
+ struct ap_state *ap = user_data;
+
+ ap_check_rekeys(ap);
+}
+
+/*
+ * Used to check/start any rekeys which are due and reset the rekey timer to the
+ * next soonest station needing a rekey.
+ *
+ * TODO: Could adapt this to also take into account the next GTK rekey and
+ * service that as well. But GTK rekeys are not yet supported in AP mode.
+ */
+static void ap_check_rekeys(struct ap_state *ap)
+{
+ const struct l_queue_entry *e;
+ uint64_t now = l_time_now();
+ uint64_t next = 0;
+
+ if (!ap->rekey_time)
+ return;
+
+ /* Find the station(s) that need a rekey and start it */
+ for (e = l_queue_get_entries(ap->sta_states); e; e = e->next) {
+ struct sta_state *sta = e->data;
+
+ if (!sta->associated || !sta->rsna || sta->rekey_time == 0)
+ continue;
+
+ if (l_time_before(now, sta->rekey_time)) {
+ uint64_t diff = l_time_diff(now, sta->rekey_time);
+
+ /* Finding the next rekey time */
+ if (next < diff)
+ next = diff;
+
+ continue;
+ }
+
+ ap_start_rekey(ap, sta);
+ }
+
+ /*
+ * Set the next rekey to the station needing it the soonest, or remove
+ * if a single station and wait until the rekey is complete to reset
+ * the timer.
+ */
+ if (next)
+ l_timeout_modify(ap->rekey_timeout, l_time_to_secs(next));
+ else {
+ l_timeout_remove(ap->rekey_timeout);
+ ap->rekey_timeout = NULL;
+ }
+}
+
+static void ap_set_sta_rekey_timer(struct ap_state *ap, struct sta_state *sta)
+{
+ if (!ap->rekey_time)
+ return;
+
+ sta->rekey_time = l_time_now() + ap->rekey_time - 1;
+
+ /*
+ * First/only station authenticated, set rekey timer. Any more stations
+ * will just set their rekey time and be serviced by the single callback
+ */
+ if (!ap->rekey_timeout)
+ ap->rekey_timeout = l_timeout_create(
+ l_time_to_secs(ap->rekey_time),
+ ap_rekey_timeout, ap, NULL);
}
static bool ap_sta_match_addr(const void *a, const void *b)
@@ -479,6 +577,8 @@ static void ap_new_rsna(struct sta_state *sta)
sta->rsna = true;
+ ap_set_sta_rekey_timer(ap, sta);
+
event_data.mac = sta->addr;
event_data.assoc_ies = sta->assoc_ies;
event_data.assoc_ies_len = sta->assoc_ies_len;
@@ -1372,6 +1472,9 @@ static void ap_handshake_event(struct handshake_state *hs,
sta->hs->go_ip_addr = IP4_FROM_STR(own_addr_str);
break;
}
+ case HANDSHAKE_EVENT_REKEY_COMPLETE:
+ ap_set_sta_rekey_timer(ap, sta);
+ return;
default:
break;
}
@@ -3628,6 +3731,19 @@ static int ap_load_config(struct ap_state *ap, const struct l_settings *config,
l_strfreev(strvval);
}
+ if (l_settings_has_key(config, "General", "RekeyTimeout")) {
+ unsigned int uintval;
+
+ if (!l_settings_get_uint(config, "General",
+ "RekeyTimeout", &uintval)) {
+ l_error("AP [General].RekeyTimeout is not valid");
+ return -EINVAL;
+ }
+
+ ap->rekey_time = uintval * L_USEC_PER_SEC;
+ } else
+ ap->rekey_time = 0;
+
/*
* Since 5GHz won't ever support only CCK rates we can ignore this
* setting on that band.
--
2.34.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v3 3/3] doc: Document RekeyTimeout for AP profiles
2023-01-18 21:17 [PATCH v3 1/3] eapol: implement rekey support for authenticator James Prestwood
2023-01-18 21:18 ` [PATCH v3 2/3] ap: support PTK rekeys James Prestwood
@ 2023-01-18 21:18 ` James Prestwood
2023-01-18 21:42 ` [PATCH v3 1/3] eapol: implement rekey support for authenticator Denis Kenzior
2 siblings, 0 replies; 4+ messages in thread
From: James Prestwood @ 2023-01-18 21:18 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
---
src/iwd.ap.rst | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/iwd.ap.rst b/src/iwd.ap.rst
index 823aba99..0763b442 100644
--- a/src/iwd.ap.rst
+++ b/src/iwd.ap.rst
@@ -67,6 +67,12 @@ The group ``[General]`` contains general AP configuration.
ensure the country is set, and that the desired frequency/channel is
unrestricted.
+ * - RekeyTimeout
+ - Timeout for PTK rekeys (seconds)
+
+ The time interval at which the AP starts a rekey for a given station. If
+ not provided a default value of 0 is used (rekeying is disabled).
+
Network Authentication Settings
-------------------------------
--
2.34.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v3 1/3] eapol: implement rekey support for authenticator
2023-01-18 21:17 [PATCH v3 1/3] eapol: implement rekey support for authenticator James Prestwood
2023-01-18 21:18 ` [PATCH v3 2/3] ap: support PTK rekeys James Prestwood
2023-01-18 21:18 ` [PATCH v3 3/3] doc: Document RekeyTimeout for AP profiles James Prestwood
@ 2023-01-18 21:42 ` Denis Kenzior
2 siblings, 0 replies; 4+ messages in thread
From: Denis Kenzior @ 2023-01-18 21:42 UTC (permalink / raw)
To: James Prestwood, iwd
Hi James,
On 1/18/23 15:17, James Prestwood wrote:
> The only changes required was to set the secure bit for message 1,
> reset the frame retry counter, and change the 2/4 verifier to use
> the rekey flag rather than ptk_complete. This is because we must
> set ptk_complete false in order to detect retransmissions of the
> 4/4 frame.
>
> Initiating a rekey can now be done by simply calling eapol_start().
> ---
> src/eapol.c | 15 ++++++++++++---
> 1 file changed, 12 insertions(+), 3 deletions(-)
>
> v3:
> * Set ek->secure to sm->rekey always to ensure retransmissions get
> the secure bit set.
>
All applied, thanks.
Regards,
-Denis
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2023-01-18 21:59 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-18 21:17 [PATCH v3 1/3] eapol: implement rekey support for authenticator James Prestwood
2023-01-18 21:18 ` [PATCH v3 2/3] ap: support PTK rekeys James Prestwood
2023-01-18 21:18 ` [PATCH v3 3/3] doc: Document RekeyTimeout for AP profiles James Prestwood
2023-01-18 21:42 ` [PATCH v3 1/3] eapol: implement rekey support for authenticator Denis Kenzior
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).