From: Michael Braun <michael-dev@xxxxxxxxxxxxx> This enables using FT RRB without configuring each other AP locally. Instead, broadcast messages are exchanged. Signed-off-by: Michael Braun <michael-dev@xxxxxxxxxxxxx> --- hostapd/hostapd.conf | 4 ++++ src/ap/wpa_auth.h | 3 +++ src/ap/wpa_auth_ft.c | 47 ++++++++++++++++++++++++++++++++++++++++------- src/ap/wpa_auth_glue.c | 9 +++++++-- 4 files changed, 54 insertions(+), 9 deletions(-) diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 7926da3..7508e03 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -1302,6 +1302,8 @@ own_ip_addr=127.0.0.1 #r0kh=02:01:02:03:04:05 r0kh-1.example.com 000102030405060708090a0b0c0d0e0f #r0kh=02:01:02:03:04:06 r0kh-2.example.com 00112233445566778899aabbccddeeff # And so on.. One line per R0KH. +# Wildcard entry: +#r0kh=ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff # List of R1KHs in the same Mobility Domain # format: <MAC address> <R1KH-ID> <128-bit key as hex string> @@ -1311,6 +1313,8 @@ own_ip_addr=127.0.0.1 #r1kh=02:01:02:03:04:05 02:11:22:33:44:55 000102030405060708090a0b0c0d0e0f #r1kh=02:01:02:03:04:06 02:11:22:33:44:66 00112233445566778899aabbccddeeff # And so on.. One line per R1KH. +# Wildcard entry: +#r1kh=00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff # Whether PMK-R1 push is enabled at R0KH # 0 = do not push PMK-R1 to all configured R1KHs (default) diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index 14c2681..40838c3 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -47,6 +47,7 @@ struct ft_rrb_frame { #define FT_R0KH_R1KH_PULL_NONCE_LEN 16 #define FT_R0KH_R1KH_PULL_DATA_LEN (FT_R0KH_R1KH_PULL_NONCE_LEN + \ + FT_R0KH_ID_MAX_LEN + 1 + \ WPA_PMK_NAME_LEN + FT_R1KH_ID_LEN + \ ETH_ALEN) #define FT_R0KH_R1KH_PULL_PAD_LEN (8 - FT_R0KH_R1KH_PULL_DATA_LEN % 8) @@ -65,6 +66,8 @@ struct ft_r0kh_r1kh_pull_frame { u8 ap_address[ETH_ALEN]; u8 nonce[FT_R0KH_R1KH_PULL_NONCE_LEN]; + u8 r0kh_id[FT_R0KH_ID_MAX_LEN]; + u8 r0kh_id_len; u8 pmk_r0_name[WPA_PMK_NAME_LEN]; u8 r1kh_id[FT_R1KH_ID_LEN]; u8 s1kh_id[ETH_ALEN]; diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index 4319112..816f6af 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -436,7 +436,7 @@ static int wpa_ft_pull_pmk_r1(struct wpa_state_machine *sm, const u8 *ies, size_t ies_len, const u8 *pmk_r0_name) { - struct ft_remote_r0kh *r0kh; + struct ft_remote_r0kh *r0kh, *r0kh_wildcard = NULL; struct ft_r0kh_r1kh_pull_frame frame, f; r0kh = sm->wpa_auth->conf.r0kh_list; @@ -445,8 +445,14 @@ static int wpa_ft_pull_pmk_r1(struct wpa_state_machine *sm, os_memcmp_const(r0kh->id, sm->r0kh_id, sm->r0kh_id_len) == 0) break; + if (r0kh->id_len == 1 && r0kh->id[0] == '*') + r0kh_wildcard = r0kh; r0kh = r0kh->next; } + if (r0kh == NULL && r0kh_wildcard != NULL) { + wpa_printf(MSG_DEBUG, "FT: Using wildcard R0KH-ID"); + r0kh = r0kh_wildcard; + } if (r0kh == NULL) { wpa_hexdump(MSG_DEBUG, "FT: Did not find R0KH-ID", sm->r0kh_id, sm->r0kh_id_len); @@ -471,6 +477,8 @@ static int wpa_ft_pull_pmk_r1(struct wpa_state_machine *sm, } os_memcpy(sm->ft_pending_pull_nonce, f.nonce, FT_R0KH_R1KH_PULL_NONCE_LEN); + os_memcpy(f.r0kh_id, sm->r0kh_id, FT_R0KH_ID_MAX_LEN); + f.r0kh_id_len = sm->r0kh_id_len; os_memcpy(f.pmk_r0_name, pmk_r0_name, WPA_PMK_NAME_LEN); os_memcpy(f.r1kh_id, sm->wpa_auth->conf.r1_key_holder, FT_R1KH_ID_LEN); os_memcpy(f.s1kh_id, sm->addr, ETH_ALEN); @@ -1608,7 +1616,7 @@ static int wpa_ft_rrb_rx_pull(struct wpa_authenticator *wpa_auth, struct ft_r0kh_r1kh_pull_frame f; const u8 *crypt; u8 *plain; - struct ft_remote_r1kh *r1kh; + struct ft_remote_r1kh *r1kh, *r1kh_wildcard = NULL; struct ft_r0kh_r1kh_resp_frame resp, r; u8 pmk_r0[PMK_LEN]; int pairwise; @@ -1624,8 +1632,15 @@ static int wpa_ft_rrb_rx_pull(struct wpa_authenticator *wpa_auth, while (r1kh) { if (os_memcmp(r1kh->addr, src_addr, ETH_ALEN) == 0) break; + if (is_zero_ether_addr(r1kh->addr) && + is_zero_ether_addr(r1kh->id)) + r1kh_wildcard = r1kh; r1kh = r1kh->next; } + if (r1kh == NULL && r1kh_wildcard != NULL) { + wpa_printf(MSG_DEBUG, "FT: Using wildcard R1KH-ID"); + r1kh = r1kh_wildcard; + } if (r1kh == NULL) { wpa_printf(MSG_DEBUG, "FT: No matching R1KH address found for " "PMK-R1 pull source address " MACSTR, @@ -1646,6 +1661,11 @@ static int wpa_ft_rrb_rx_pull(struct wpa_authenticator *wpa_auth, return -1; } + if (f.r0kh_id_len != wpa_auth->conf.r0_key_holder_len || + os_memcmp_const(f.r0kh_id, wpa_auth->conf.r0_key_holder, + f.r0kh_id_len) != 0) + return -1; + wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - nonce", f.nonce, sizeof(f.nonce)); wpa_hexdump(MSG_DEBUG, "FT: PMK-R1 pull - PMKR0Name", @@ -1748,7 +1768,7 @@ static int wpa_ft_rrb_rx_resp(struct wpa_authenticator *wpa_auth, struct ft_r0kh_r1kh_resp_frame f; const u8 *crypt; u8 *plain; - struct ft_remote_r0kh *r0kh; + struct ft_remote_r0kh *r0kh, *r0kh_wildcard = NULL; int pairwise, res; int expiresIn; int maxExpiresIn = wpa_auth->conf.r0_key_lifetime * 60; @@ -1762,8 +1782,14 @@ static int wpa_ft_rrb_rx_resp(struct wpa_authenticator *wpa_auth, while (r0kh) { if (os_memcmp(r0kh->addr, src_addr, ETH_ALEN) == 0) break; + if (r0kh->id_len == 1 && r0kh->id[0] == '*') + r0kh_wildcard = r0kh; r0kh = r0kh->next; } + if (r0kh == NULL && r0kh_wildcard != NULL) { + wpa_printf(MSG_DEBUG, "FT: Using wildcard R0KH-ID"); + r0kh = r0kh_wildcard; + } if (r0kh == NULL) { wpa_printf(MSG_DEBUG, "FT: No matching R0KH address found for " "PMK-R0 pull response source address " MACSTR, @@ -1825,7 +1851,7 @@ static int wpa_ft_rrb_rx_push(struct wpa_authenticator *wpa_auth, struct ft_r0kh_r1kh_push_frame f; const u8 *crypt; u8 *plain; - struct ft_remote_r0kh *r0kh; + struct ft_remote_r0kh *r0kh, *r0kh_wildcard = NULL; struct os_time now; os_time_t tsend; int pairwise; @@ -1841,8 +1867,14 @@ static int wpa_ft_rrb_rx_push(struct wpa_authenticator *wpa_auth, while (r0kh) { if (os_memcmp(r0kh->addr, src_addr, ETH_ALEN) == 0) break; + if (r0kh->id_len == 1 && r0kh->id[0] == '*') + r0kh_wildcard = r0kh; r0kh = r0kh->next; } + if (r0kh == NULL && r0kh_wildcard != NULL) { + wpa_printf(MSG_DEBUG, "FT: Using wildcard R0KH-ID"); + r0kh = r0kh_wildcard; + } if (r0kh == NULL) { wpa_printf(MSG_DEBUG, "FT: No matching R0KH address found for " "PMK-R0 push source address " MACSTR, @@ -2106,11 +2138,12 @@ void wpa_ft_push_pmk_r1(struct wpa_authenticator *wpa_auth, const u8 *addr) wpa_printf(MSG_DEBUG, "FT: Deriving and pushing PMK-R1 keys to R1KHs " "for STA " MACSTR, MAC2STR(addr)); - r1kh = wpa_auth->conf.r1kh_list; - while (r1kh) { + for (r1kh = wpa_auth->conf.r1kh_list; r1kh; r1kh = r1kh->next) { + if (is_zero_ether_addr(r1kh->addr) || + is_zero_ether_addr(r1kh->id)) + continue; wpa_ft_generate_pmk_r1(wpa_auth, r0, r1kh, addr, r0->pairwise, expiresIn); - r1kh = r1kh->next; } } diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index ee34012..3736d4a 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -418,6 +418,9 @@ static int hostapd_wpa_auth_ft_iter(struct hostapd_iface *iface, void *ctx) struct wpa_auth_ft_iface_iter_data *idata = ctx; struct hostapd_data *hapd; size_t j; + int multicast; + + multicast = is_multicast_ether_addr(idata->dst); for (j = 0; j < iface->num_bss; j++) { hapd = iface->bss[j]; @@ -425,7 +428,8 @@ static int hostapd_wpa_auth_ft_iter(struct hostapd_iface *iface, void *ctx) continue; if (!hapd->wpa_auth) continue; - if (os_memcmp(hapd->own_addr, idata->dst, ETH_ALEN) == 0) { + if (os_memcmp(hapd->own_addr, idata->dst, ETH_ALEN) == 0 || + multicast) { wpa_printf(MSG_DEBUG, "FT: Send RRB data directly to " "locally managed BSS " MACSTR "@%s -> " MACSTR "@%s", @@ -435,7 +439,8 @@ static int hostapd_wpa_auth_ft_iter(struct hostapd_iface *iface, void *ctx) wpa_ft_rrb_rx(hapd->wpa_auth, idata->src_hapd->own_addr, idata->data, idata->data_len); - return 1; + if (!multicast) + return 1; } } -- 1.9.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap