From patchwork Sat Sep 24 20:53:45 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: michael-dev X-Patchwork-Id: 674416 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2001:1868:205::9]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3shNZK0hmnz9s5g for ; Sun, 25 Sep 2016 07:26:01 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bnuSB-0002v6-Ap; Sat, 24 Sep 2016 21:25:47 +0000 Received: from merlin.infradead.org ([2001:4978:20e::2]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1bnuPj-0007b6-Bf for hostap@bombadil.infradead.org; Sat, 24 Sep 2016 21:23:15 +0000 Received: from mail.fem.tu-ilmenau.de ([141.24.220.54]) by merlin.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bnu2y-0000zz-Hl for hostap@lists.infradead.org; Sat, 24 Sep 2016 20:59:45 +0000 Received: from localhost (localhost [127.0.0.1]) by mail.fem.tu-ilmenau.de (Postfix) with ESMTP id 042A26833; Sat, 24 Sep 2016 22:54:18 +0200 (CEST) X-Virus-Scanned: amavisd-new at fem.tu-ilmenau.de Received: from mail.fem.tu-ilmenau.de ([127.0.0.1]) by localhost (mail.fem.tu-ilmenau.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id GPXHYQiZ4jXi; Sat, 24 Sep 2016 22:54:17 +0200 (CEST) Received: from mail-backup.fem.tu-ilmenau.de (mail-backup.net.fem.tu-ilmenau.de [10.42.40.22]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.fem.tu-ilmenau.de (Postfix) with ESMTPS; Sat, 24 Sep 2016 22:54:17 +0200 (CEST) Received: from a234.fem.tu-ilmenau.de (ray-controller.net.fem.tu-ilmenau.de [10.42.51.234]) by mail-backup.fem.tu-ilmenau.de (Postfix) with ESMTP id CDC415604D; Sat, 24 Sep 2016 22:54:17 +0200 (CEST) Received: by a234.fem.tu-ilmenau.de (Postfix, from userid 1000) id BE83E3020ED0; Sat, 24 Sep 2016 22:54:17 +0200 (CEST) From: Michael Braun To: hostap@lists.infradead.org Subject: [PATCH v2 04/33] FT: add support for wildcard R0KH / R1KH Date: Sat, 24 Sep 2016 22:53:45 +0200 Message-Id: <1474750454-6626-5-git-send-email-michael-dev@fami-braun.de> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1474750454-6626-1-git-send-email-michael-dev@fami-braun.de> References: <1474750454-6626-1-git-send-email-michael-dev@fami-braun.de> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160924_165944_810851_CE7C4D8B X-CRM114-Status: GOOD ( 12.78 ) X-Spam-Score: -4.2 (----) X-Spam-Report: SpamAssassin version 3.4.1 on merlin.infradead.org summary: Content analysis details: (-4.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [141.24.220.54 listed in list.dnswl.org] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: projekt-wlan@fem.tu-ilmenau.de, Michael Braun MIME-Version: 1.0 Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org This enables using FT RRB without configuring each other AP locally. Instead, broadcast messages are exchanged. Signed-off-by: Michael Braun --- 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 dab4a4e..26546de 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -1306,6 +1306,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: <128-bit key as hex string> @@ -1315,6 +1317,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 5712884..39a1afd 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -44,6 +44,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) % 8) @@ -55,6 +56,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 e0e0740..04e9bf8 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -316,7 +316,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; @@ -325,8 +325,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); @@ -351,6 +357,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); @@ -1423,7 +1431,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; @@ -1437,8 +1445,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, @@ -1459,6 +1474,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", @@ -1559,7 +1579,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; wpa_printf(MSG_DEBUG, "FT: Received PMK-R1 pull response"); @@ -1571,8 +1591,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, @@ -1628,7 +1654,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; @@ -1642,8 +1668,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, @@ -1892,10 +1924,11 @@ 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); - r1kh = r1kh->next; } } diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index 2a5a940..12b9ccc 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -417,6 +417,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]; @@ -424,7 +427,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", @@ -434,7 +438,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; } }