From patchwork Wed Dec 16 11:01:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilan Peer X-Patchwork-Id: 1417067 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=2xgPSU0v; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Cwspt074tz9sSs for ; Wed, 16 Dec 2020 22:09:57 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=v5eosNvzzBuBc3xWV4dYrOVzoi2JcNfhu3KVElBMA5Y=; b=2xgPSU0v55B/hNLIo841KfEg57 /TNBhfs6mbW1aF/U+r8CjwVBB+WBCERa+2vzIDuvoVkwnzxQcrwUpqsSZvyeM7Isx2IlQMR2h/eJG p9mnLUHruR2KOfOCfh3jvWNWWotaP8ZwPKfkJXGaLsPrubzcCtgxNy4Ycse8K/F0ydjJe1DWL05Q2 bkY2IXHLGBk1E/q3DFiBp1ZzS5NHHKSHfaOMXYRFdWnP8vS3x3wLXnc6Hvhiv4uosOwFVsfZ3w7Oq sHZggxPTTJXogeI2X0Cn47DrJwqVdTvL8xJHH7YJhfM3Eetkg/zoMTgXchKmO0u5nIWdagM+i0fKZ bcRn8ilg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kpUfx-0000PE-RG; Wed, 16 Dec 2020 11:08:57 +0000 Received: from mga09.intel.com ([134.134.136.24]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kpUYy-0004NO-N2 for hostap@lists.infradead.org; Wed, 16 Dec 2020 11:01:47 +0000 IronPort-SDR: 1TmxGrWARUD5bYhlY4A/mvFpEJl0eAWV+LXHaya2DlQe1iYo1BEi/YeRQ0QcHAU8i6B8jSyQ25 x+0UklkA6r4Q== X-IronPort-AV: E=McAfee;i="6000,8403,9836"; a="175192463" X-IronPort-AV: E=Sophos;i="5.78,424,1599548400"; d="scan'208";a="175192463" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Dec 2020 03:01:42 -0800 IronPort-SDR: 1vkxrtaOrQLnT4/w56Kui9NfxhzWKvT5BrkHHTTQulANYYqvlLosFYyJHeUTDvsdQ5JttSrNlH jsjVmm8QPDyw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.78,424,1599548400"; d="scan'208";a="412545966" Received: from jed01615.jer.intel.com ([10.12.190.15]) by orsmga001.jf.intel.com with ESMTP; 16 Dec 2020 03:01:41 -0800 From: Ilan Peer To: hostap@lists.infradead.org Subject: [PATCH 1/4] RSN: Add RSNXE new definitions Date: Wed, 16 Dec 2020 13:01:37 +0200 Message-Id: <20201216110140.8440-2-ilan.peer@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201216110140.8440-1-ilan.peer@intel.com> References: <20201216110140.8440-1-ilan.peer@intel.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201216_060144_966862_5350208C X-CRM114-Status: GOOD ( 23.07 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [134.134.136.24 listed in list.dnswl.org] 0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [134.134.136.24 listed in wl.mailspike.net] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Draft P802.11az_D2.6 defined the following additional capabilities to the RSNXE information element: - Secure LTF support - Secure RTT support - Protection of range negotiation and measurement management frames. Add support for adverting the new capabilities. Signed-off-by: Ilan Peer --- src/ap/ieee802_11_shared.c | 46 +++++++++++++++++++++++++----------- src/ap/wpa_auth.h | 7 +++++- src/ap/wpa_auth_glue.c | 7 ++++++ src/ap/wpa_auth_ie.c | 39 +++++++++++++++++++++--------- src/common/ieee802_11_defs.h | 5 ++++ src/drivers/driver.h | 9 +++++++ src/rsn_supp/wpa_i.h | 7 +++++- src/rsn_supp/wpa_ie.c | 42 ++++++++++++++++++++++---------- 8 files changed, 122 insertions(+), 40 deletions(-) diff --git a/src/ap/ieee802_11_shared.c b/src/ap/ieee802_11_shared.c index 17003d5067..7b544d14a0 100644 --- a/src/ap/ieee802_11_shared.c +++ b/src/ap/ieee802_11_shared.c @@ -1095,6 +1095,7 @@ int get_tx_parameters(struct sta_info *sta, int ap_max_chanwidth, u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len) { + size_t ie_len = 1; u8 *pos = eid; bool sae_pk = false; @@ -1102,24 +1103,41 @@ u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len) sae_pk = hostapd_sae_pk_in_use(hapd->conf); #endif /* CONFIG_SAE_PK */ - if (!(hapd->conf->wpa & WPA_PROTO_RSN) || - !wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) || - (hapd->conf->sae_pwe != 1 && hapd->conf->sae_pwe != 2 && - !hostapd_sae_pw_id_in_use(hapd->conf) && !sae_pk) || - hapd->conf->sae_pwe == 3 || - len < 3) + if (hapd->iface->drv_flags2 & (WPA_DRIVER_FLAGS2_SEC_LTF | + WPA_DRIVER_FLAGS2_SEC_RTT | + WPA_DRIVER_FLAGS2_PROT_RANGE_NEG)) + ie_len = 2; + + if (!(hapd->conf->wpa & WPA_PROTO_RSN) || len < (2 + ie_len)) return pos; *pos++ = WLAN_EID_RSNX; - *pos++ = 1; - /* bits 0-3 = 0 since only one octet of Extended RSN Capabilities is - * used for now */ - *pos = BIT(WLAN_RSNX_CAPAB_SAE_H2E); + *pos++ = ie_len; + *pos = ie_len - 1; + + if (wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) && + (hapd->conf->sae_pwe == 1 || hapd->conf->sae_pwe == 2 || + hostapd_sae_pw_id_in_use(hapd->conf) || sae_pk) && hapd->conf->sae_pwe != 3) { + *pos |= BIT(WLAN_RSNX_CAPAB_SAE_H2E); #ifdef CONFIG_SAE_PK - if (sae_pk) - *pos |= BIT(WLAN_RSNX_CAPAB_SAE_PK); + if (sae_pk) + *pos |= BIT(WLAN_RSNX_CAPAB_SAE_PK); #endif /* CONFIG_SAE_PK */ - pos++; + } - return pos; + if (!*pos) + return eid; + + *++pos = 0; + + if (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF) + *pos |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF); + + if (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_RTT) + *pos |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT); + + if (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG) + *pos |= BIT(WLAN_RSNX_CAPAB_PROT_RANGE_NEG); + + return eid + 2 + ie_len; } diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index f0e8d8f66d..129c65433d 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -256,7 +256,12 @@ struct wpa_auth_config { u8 fils_cache_id[FILS_CACHE_ID_LEN]; #endif /* CONFIG_FILS */ int sae_pwe; - bool sae_pk; + + unsigned int sae_pk:1; + unsigned int secure_ltf:1; + unsigned int secure_rtt:1; + unsigned int prot_range_neg:1; + int owe_ptk_workaround; u8 transition_disable; #ifdef CONFIG_DPP2 diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index 9183e1b659..0e9b838127 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -1510,6 +1510,13 @@ int hostapd_setup_wpa(struct hostapd_data *hapd) else _conf.extended_key_id = 0; + _conf.secure_ltf = + !!(hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF); + _conf.secure_rtt = + !!(hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_RTT); + _conf.prot_range_neg = + !!(hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG); + hapd->wpa_auth = wpa_init(hapd->own_addr, &_conf, &cb, hapd); if (hapd->wpa_auth == NULL) { wpa_printf(MSG_ERROR, "WPA initialization failed."); diff --git a/src/ap/wpa_auth_ie.c b/src/ap/wpa_auth_ie.c index 972ca84b6e..de2c07ec68 100644 --- a/src/ap/wpa_auth_ie.c +++ b/src/ap/wpa_auth_ie.c @@ -383,26 +383,43 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len, int wpa_write_rsnxe(struct wpa_auth_config *conf, u8 *buf, size_t len) { + size_t ie_len = 1; u8 *pos = buf; - if (conf->sae_pwe != 1 && conf->sae_pwe != 2 && !conf->sae_pk) - return 0; /* no supported extended RSN capabilities */ + if (conf->secure_ltf || conf->secure_rtt || conf->prot_range_neg) + ie_len = 2; - if (len < 3) + if (len < 2 + ie_len) return -1; *pos++ = WLAN_EID_RSNX; - *pos++ = 1; - /* bits 0-3 = 0 since only one octet of Extended RSN Capabilities is - * used for now */ - *pos = BIT(WLAN_RSNX_CAPAB_SAE_H2E); + *pos++ = ie_len; + *pos = ie_len - 1; + + if (wpa_key_mgmt_sae(conf->wpa_key_mgmt) && + (conf->sae_pwe == 1 || conf->sae_pwe == 2)) { + *pos |= BIT(WLAN_RSNX_CAPAB_SAE_H2E); #ifdef CONFIG_SAE_PK - if (conf->sae_pk) - *pos |= BIT(WLAN_RSNX_CAPAB_SAE_PK); + if (conf->sae_pk) + *pos |= BIT(WLAN_RSNX_CAPAB_SAE_PK); #endif /* CONFIG_SAE_PK */ - pos++; + } - return pos - buf; + if (!*pos) + return 0; + + *++pos = 0; + + if (conf->secure_ltf) + *pos |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF); + + if (conf->secure_rtt) + *pos |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT); + + if (conf->prot_range_neg) + *pos |= BIT(WLAN_RSNX_CAPAB_PROT_RANGE_NEG); + + return 2 + ie_len; } diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 2705589bca..88f990205c 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -579,6 +579,11 @@ #define WLAN_RSNX_CAPAB_SAE_H2E 5 #define WLAN_RSNX_CAPAB_SAE_PK 6 +/* Extended RSN Capabilities 2nd octect */ +#define WLAN_RSNX_CAPAB_SECURE_LTF 0 +#define WLAN_RSNX_CAPAB_SECURE_RTT 1 +#define WLAN_RSNX_CAPAB_PROT_RANGE_NEG 2 + /* Action frame categories (IEEE Std 802.11-2016, 9.4.1.11, Table 9-76) */ #define WLAN_ACTION_SPECTRUM_MGMT 0 #define WLAN_ACTION_QOS 1 diff --git a/src/drivers/driver.h b/src/drivers/driver.h index b0543e7b42..f737aecae1 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1950,6 +1950,15 @@ struct wpa_driver_capa { #define WPA_DRIVER_FLAGS2_CONTROL_PORT_RX 0x0000000000000001ULL /** Driver supports TX status reports for EAPOL frames through control port */ #define WPA_DRIVER_FLAGS2_CONTROL_PORT_TX_STATUS 0x0000000000000002ULL +/** Driver supports secure LTF */ +#define WPA_DRIVER_FLAGS2_SEC_LTF 0x0000000000000004ULL +/** Driver supports secure RTT measurement exchange */ +#define WPA_DRIVER_FLAGS2_SEC_RTT 0x0000000000000008ULL +/** + * Driver supports protection of range negotiation and measurement management + * frames + */ +#define WPA_DRIVER_FLAGS2_PROT_RANGE_NEG 0x0000000000000010ULL u64 flags2; #define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \ diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index 72a6023dd3..5f68282617 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -105,8 +105,13 @@ struct wpa_sm { int rsn_enabled; /* Whether RSN is enabled in configuration */ int mfp; /* 0 = disabled, 1 = optional, 2 = mandatory */ int ocv; /* Operating Channel Validation */ + int sae_pwe; /* SAE PWE generation options */ - int sae_pk; /* whether SAE-PK is used */ + + unsigned int sae_pk:1; /* whether SAE-PK is used */ + unsigned int secure_ltf:1; + unsigned int secure_rtt:1; + unsigned int prot_range_neg:1; u8 *assoc_wpa_ie; /* Own WPA/RSN IE from (Re)AssocReq */ size_t assoc_wpa_ie_len; diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c index 20fdd6987f..dd9088c152 100644 --- a/src/rsn_supp/wpa_ie.c +++ b/src/rsn_supp/wpa_ie.c @@ -353,26 +353,42 @@ int wpa_gen_wpa_ie(struct wpa_sm *sm, u8 *wpa_ie, size_t wpa_ie_len) int wpa_gen_rsnxe(struct wpa_sm *sm, u8 *rsnxe, size_t rsnxe_len) { + size_t ie_len = 1; u8 *pos = rsnxe; - if (!wpa_key_mgmt_sae(sm->key_mgmt)) - return 0; /* SAE not in use */ - if (sm->sae_pwe != 1 && sm->sae_pwe != 2 && !sm->sae_pk) - return 0; /* no supported extended RSN capabilities */ + if (sm->secure_ltf || sm->secure_rtt || sm->prot_range_neg) + ie_len = 2; - if (rsnxe_len < 3) + if (rsnxe_len < 2 + ie_len) return -1; *pos++ = WLAN_EID_RSNX; - *pos++ = 1; - /* bits 0-3 = 0 since only one octet of Extended RSN Capabilities is - * used for now */ - *pos = BIT(WLAN_RSNX_CAPAB_SAE_H2E); + *pos++ = ie_len; + *pos = ie_len - 1; + + /* Indicate the SAE H2E is supported */ + if (wpa_key_mgmt_sae(sm->key_mgmt) && + (sm->sae_pwe == 1 || sm->sae_pwe == 2 || sm->sae_pk)) { + *pos |= BIT(WLAN_RSNX_CAPAB_SAE_H2E); #ifdef CONFIG_SAE_PK - if (sm->sae_pk) - *pos |= BIT(WLAN_RSNX_CAPAB_SAE_PK); + if (sm->sae_pk) + *pos |= BIT(WLAN_RSNX_CAPAB_SAE_PK); #endif /* CONFIG_SAE_PK */ - pos++; + } + + if (!*pos) + return 0; + + *++pos = 0; + + if (sm->secure_ltf) + *pos |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF); + + if (sm->secure_rtt) + *pos |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT); + + if (sm->prot_range_neg) + *pos |= BIT(WLAN_RSNX_CAPAB_PROT_RANGE_NEG); - return pos - rsnxe; + return 2 + ie_len; } From patchwork Wed Dec 16 11:01:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilan Peer X-Patchwork-Id: 1417064 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=245vTM+C; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Cwspr0YfMz9sVH for ; Wed, 16 Dec 2020 22:09:55 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=7u6Dp7c7SEKZ4Ln65MVcYzYMtgfOjIkLuUUH5+LVs+E=; b=245vTM+CZVsGyMb7NPaGCO/YKy BXf69q8FHfu7VXsnb8lb7qv0SX4IvmEm7g1U3rFBl7hsVKYiFwL6QF7TKsmE5D94kbEw7/osHpTGx /mEBnAkCS7wS5jHOF/laq6s+iqtdrrzQ3kFfbcBeZtpLfalUD4d9glI7UVg5T/NbhyozMI+HGIs5w uDrsQJKACZBwVj7sLrFP5i4j1G3zkN5qjP0IB5drGRDNXdbW21qPxzXGBG61Qe2znjcD2l4I+Gjqb aj/ZaK31xdld90a3+ZCUATXvyWx/udYTv2neXFxbI0sBWQIi9G5LsoTLcdLupLJ8F+iSbQiIE8Zdg CQnK1ECw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kpUfv-0000Ol-Pf; Wed, 16 Dec 2020 11:08:55 +0000 Received: from mga09.intel.com ([134.134.136.24]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kpUYy-0003up-B4 for hostap@lists.infradead.org; Wed, 16 Dec 2020 11:01:47 +0000 IronPort-SDR: EzF+dZG++QDgzM3ZTCWm68Gd0MColy0pkbsnjoa4UXMr73UbqtDYvw6tYx10eeX8D6s4C8kspe btcOx+dvzwdg== X-IronPort-AV: E=McAfee;i="6000,8403,9836"; a="175192470" X-IronPort-AV: E=Sophos;i="5.78,424,1599548400"; d="scan'208";a="175192470" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Dec 2020 03:01:44 -0800 IronPort-SDR: e0MZu7kLkTgSQ1jqR1TAYsdRk9KXAT4kHeLwcgsEET4I++WFMcTMv1UZLG/hrEISDjeeIBmVWh fIu0g7rxIYBQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.78,424,1599548400"; d="scan'208";a="412545986" Received: from jed01615.jer.intel.com ([10.12.190.15]) by orsmga001.jf.intel.com with ESMTP; 16 Dec 2020 03:01:42 -0800 From: Ilan Peer To: hostap@lists.infradead.org Subject: [PATCH 2/4] PASN: Include RSNXE in the PASN negotiation Date: Wed, 16 Dec 2020 13:01:38 +0200 Message-Id: <20201216110140.8440-3-ilan.peer@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201216110140.8440-1-ilan.peer@intel.com> References: <20201216110140.8440-1-ilan.peer@intel.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201216_060144_619918_7EE47798 X-CRM114-Status: GOOD ( 22.53 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [134.134.136.24 listed in list.dnswl.org] 0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [134.134.136.24 listed in wl.mailspike.net] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Draft P802.11az_D2.6 added definitions to include RSNXE in the PASN negotiation. Implement the new functionality in both wpa_supplicant and hostapd. Signed-off-by: Ilan Peer --- src/ap/beacon.c | 2 +- src/ap/beacon.h | 2 ++ src/ap/ieee802_11.c | 34 ++++++++++++++++++---- src/common/wpa_common.c | 48 +++++++++++++++++++++++++++++-- src/common/wpa_common.h | 4 +++ wpa_supplicant/pasn_supplicant.c | 41 +++++++++++++++++++------- wpa_supplicant/wpa_supplicant_i.h | 2 +- 7 files changed, 114 insertions(+), 19 deletions(-) diff --git a/src/ap/beacon.c b/src/ap/beacon.c index 47b260e810..22f0751ca6 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -266,7 +266,7 @@ static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid, } -static const u8 * hostapd_wpa_ie(struct hostapd_data *hapd, u8 eid) +const u8 *hostapd_wpa_ie(struct hostapd_data *hapd, u8 eid) { const u8 *ies; size_t ies_len; diff --git a/src/ap/beacon.h b/src/ap/beacon.h index a26e30879c..8f09fda1a7 100644 --- a/src/ap/beacon.h +++ b/src/ap/beacon.h @@ -30,4 +30,6 @@ sta_track_seen_on(struct hostapd_iface *iface, const u8 *addr, void sta_track_claim_taxonomy_info(struct hostapd_iface *iface, const u8 *addr, struct wpabuf **probe_ie_taxonomy); +const u8 *hostapd_wpa_ie(struct hostapd_data *hapd, u8 eid); + #endif /* BEACON_H */ diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 1da7eff4fb..52de046535 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -2939,9 +2939,10 @@ static int handle_auth_pasn_resp(struct hostapd_data *hapd, { struct wpabuf *buf, *pubkey = NULL, *wrapped_data_buf = NULL; u8 mic[WPA_PASN_MAX_MIC_LEN]; - u8 mic_len, data_len; + u8 mic_len, frame_len, data_len; u8 *ptr; - const u8 *data, *rsn_ie; + const u8 *frame, *rsn_ie, *rsnxe_ie; + u8 *data; size_t rsn_ie_len; int ret; @@ -2986,6 +2987,11 @@ static int handle_auth_pasn_resp(struct hostapd_data *hapd, wpabuf_free(pubkey); pubkey = NULL; + /* Add RSNXE if needed */ + rsnxe_ie = hostapd_wpa_ie(hapd, WLAN_EID_RSNX); + if (rsnxe_ie) + wpabuf_put_data(buf, rsnxe_ie, 2 + rsnxe_ie[1]); + /* Add the mic */ mic_len = pasn_mic_len(sta->pasn->akmp, sta->pasn->cipher); wpabuf_put_u8(buf, WLAN_EID_MIC); @@ -2994,8 +3000,8 @@ static int handle_auth_pasn_resp(struct hostapd_data *hapd, os_memset(ptr, 0, mic_len); - data = wpabuf_head(buf) + IEEE80211_HDRLEN; - data_len = wpabuf_len(buf) - IEEE80211_HDRLEN; + frame = wpabuf_head(buf) + IEEE80211_HDRLEN; + frame_len = wpabuf_len(buf) - IEEE80211_HDRLEN; rsn_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &rsn_ie_len); if (!rsn_ie || !rsn_ie_len) @@ -3006,11 +3012,29 @@ static int handle_auth_pasn_resp(struct hostapd_data *hapd, * also the MD IE etc. Thus, do not use the returned length but instead * use the length specified in the IE header. */ + data_len = rsn_ie[1] + 2; + if (rsnxe_ie) { + data = os_zalloc(rsn_ie[1] + 2 + rsnxe_ie[1] + 2); + if (!data) + goto fail; + + os_memcpy(data, (u8 *)rsn_ie, rsn_ie[1] + 2); + os_memcpy(data + rsn_ie[1] + 2, (u8 *)rsnxe_ie, + rsnxe_ie[1] + 2); + data_len += rsnxe_ie[1] + 2; + } else { + data = (u8 *)rsn_ie; + } + ret = pasn_mic(sta->pasn->ptk.kck, sta->pasn->akmp, sta->pasn->cipher, hapd->own_addr, sta->addr, - rsn_ie, rsn_ie[1] + 2, data, data_len, + frame, frame_len, mic); + + if (rsnxe_ie) + os_free(data); + if (ret) { wpa_printf(MSG_DEBUG, "PASN: frame 3: Failed mic calculation"); goto fail; diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c index 6300d774b4..3acaa7e261 100644 --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c @@ -1322,8 +1322,8 @@ u8 pasn_mic_len(int akmp, int cipher) * @addr2: for the 2nd PASN frame the BSSID; for the 3rd frame the supplicant * address * @data: For calculating the MIC for the 2nd PASN frame, this should hold the - * beacon RSN IE. For the calculating the MIC for the 3rd PASN frame, this - * should hold the HASH of body of the PASN 1st frame. + * beacon RSN IE + RSNXE IE. For calculating the MIC for the 3rd PASN + * frame, this should hold the HASH of body of the PASN 1st frame. * @data_len: the length of data * @frame: The body of the PASN frame including the MIC element with the Octets * in the MIC field of the MIC element set to 0. @@ -3667,4 +3667,48 @@ int wpa_pasn_parse_parameter_ie(const u8 *data, u8 len, return 0; } + +void wpa_pasn_add_rsnxe(struct wpabuf *buf, u8 prot_twt, u8 sae_h2e, + u8 sae_pk, u8 sec_ltf, u8 sec_rtt, u8 prot_range_neg) +{ + u8 len = 1; + u8 capab = 0; + + if (sec_ltf || sec_rtt || prot_range_neg) { + len = 2; + capab = 1; + } + + if (prot_twt) + capab |= BIT(WLAN_RSNX_CAPAB_PROTECTED_TWT); + + if (sae_h2e) + capab |= BIT(WLAN_RSNX_CAPAB_SAE_H2E); + + if (sae_pk) + capab |= BIT(WLAN_RSNX_CAPAB_SAE_PK); + + if (!capab) + return; + + wpabuf_put_u8(buf, WLAN_EID_RSNX); + wpabuf_put_u8(buf, len); + wpabuf_put_u8(buf, capab); + + if (len == 1) + return; + + capab = 0; + if (sec_ltf) + capab |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF); + + if (sec_rtt) + capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT); + + if (prot_range_neg) + capab |= BIT(WLAN_RSNX_CAPAB_PROT_RANGE_NEG); + + wpabuf_put_u8(buf, capab); +} + #endif /* CONFIG_PASN */ diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h index a094686d4e..89637e56d5 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -21,6 +21,7 @@ #define WPA_GTK_MAX_LEN 32 #define WPA_PASN_PMK_LEN 32 #define WPA_PASN_MAX_MIC_LEN 24 +#define WPA_MAX_RSNXE_LEN 4 #define OWE_DH_GROUP 19 @@ -664,4 +665,7 @@ int wpa_pasn_validate_rsne(const struct wpa_ie_data *data); int wpa_pasn_parse_parameter_ie(const u8 *data, u8 len, struct wpa_pasn_params_data *pasn_params); +void wpa_pasn_add_rsnxe(struct wpabuf *buf, u8 prot_twt, u8 sae_h2e, + u8 sae_pk, u8 sec_ltf, u8 sec_rtt, u8 prot_range_neg); + #endif /* WPA_COMMON_H */ diff --git a/wpa_supplicant/pasn_supplicant.c b/wpa_supplicant/pasn_supplicant.c index bdf72d51c6..32a8a33bb6 100644 --- a/wpa_supplicant/pasn_supplicant.c +++ b/wpa_supplicant/pasn_supplicant.c @@ -708,6 +708,17 @@ static struct wpabuf *wpas_pasn_build_auth_1(struct wpa_supplicant *wpa_s, wpa_pasn_add_wrapped_data(buf, wrapped_data_buf); + /* + * add own RNSXE + * TODO: How to handle protected TWT and SAE H2E + */ + wpa_pasn_add_rsnxe(buf, + 0, 0, 0, + !!(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF), + !!(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_RTT), + !!(wpa_s->drv_flags2 & + WPA_DRIVER_FLAGS2_PROT_RANGE_NEG)); + ret = pasn_auth_frame_hash(pasn->akmp, pasn->cipher, wpabuf_head(buf) + IEEE80211_HDRLEN, wpabuf_len(buf) - IEEE80211_HDRLEN, @@ -829,8 +840,8 @@ static void wpas_pasn_reset(struct wpa_supplicant *wpa_s) os_memset(&pasn->ptk, 0, sizeof(pasn->ptk)); os_memset(&pasn->hash, 0, sizeof(pasn->hash)); - wpabuf_free(pasn->beacon_rsne); - pasn->beacon_rsne = NULL; + wpabuf_free(pasn->beacon_rsne_rsnxe); + pasn->beacon_rsne_rsnxe = NULL; wpabuf_free(pasn->comeback); pasn->comeback = NULL; @@ -950,6 +961,7 @@ static int wpas_pasn_set_pmk(struct wpa_supplicant *wpa_s, static int wpas_pasn_start(struct wpa_supplicant *wpa_s, const u8 *bssid, int akmp, int cipher, u16 group, int freq, const u8 *beacon_rsne, u8 beacon_rsne_len, + const u8 *beacon_rsnxe, u8 beacon_rsnxe_len, int network_id, struct wpabuf *comeback) { struct wpas_pasn *pasn = &wpa_s->pasn; @@ -1000,13 +1012,18 @@ static int wpas_pasn_start(struct wpa_supplicant *wpa_s, const u8 *bssid, goto fail; } - pasn->beacon_rsne = wpabuf_alloc(beacon_rsne_len); - if (!pasn->beacon_rsne) { - wpa_printf(MSG_DEBUG, "PASN: Failed storing beacon RSNE"); + pasn->beacon_rsne_rsnxe = wpabuf_alloc(beacon_rsne_len + + beacon_rsnxe_len); + if (!pasn->beacon_rsne_rsnxe) { + wpa_printf(MSG_DEBUG, "PASN: Failed storing beacon RSNE/RSNXE"); goto fail; } - wpabuf_put_data(pasn->beacon_rsne, beacon_rsne, beacon_rsne_len); + wpabuf_put_data(pasn->beacon_rsne_rsnxe, beacon_rsne, beacon_rsne_len); + + if (beacon_rsnxe && beacon_rsnxe_len) + wpabuf_put_data(pasn->beacon_rsne_rsnxe, beacon_rsnxe, + beacon_rsnxe_len); pasn->akmp = akmp; pasn->cipher = cipher; @@ -1092,7 +1109,7 @@ static void wpas_pasn_auth_start_cb(struct wpa_radio_work *work, int deinit) struct wpa_supplicant *wpa_s = work->wpa_s; struct wpa_pasn_auth_work *awork = work->ctx; struct wpa_bss *bss; - const u8 *rsne; + const u8 *rsne, *rsnxe; int ret; wpa_printf(MSG_DEBUG, "PASN: auth_start_cb: deinit=%d", deinit); @@ -1127,9 +1144,13 @@ static void wpas_pasn_auth_start_cb(struct wpa_radio_work *work, int deinit) goto fail; } + rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX); + ret = wpas_pasn_start(wpa_s, awork->bssid, awork->akmp, awork->cipher, awork->group, bss->freq, - rsne, *(rsne + 1) + 2, awork->network_id, + rsne, *(rsne + 1) + 2, + rsnxe, rsnxe ? *(rsnxe + 1) + 2 : 0, + awork->network_id, awork->comeback); if (ret) { wpa_printf(MSG_DEBUG, @@ -1425,8 +1446,8 @@ int wpas_pasn_auth_rx(struct wpa_supplicant *wpa_s, /* verify the MIC */ ret = pasn_mic(pasn->ptk.kck, pasn->akmp, pasn->cipher, pasn->bssid, wpa_s->own_addr, - wpabuf_head(pasn->beacon_rsne), - wpabuf_len(pasn->beacon_rsne), + wpabuf_head(pasn->beacon_rsne_rsnxe), + wpabuf_len(pasn->beacon_rsne_rsnxe), (u8 *)&mgmt->u.auth, len - offsetof(struct ieee80211_mgmt, u.auth), out_mic); diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 3114b60dd2..47cf19f857 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -549,7 +549,7 @@ struct wpas_pasn { u8 hash[SHA384_MAC_LEN]; - struct wpabuf *beacon_rsne; + struct wpabuf *beacon_rsne_rsnxe; struct wpa_ptk ptk; struct crypto_ecdh *ecdh; From patchwork Wed Dec 16 11:01:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilan Peer X-Patchwork-Id: 1417069 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=MCaWVs3K; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Cwspz363Yz9sTX for ; Wed, 16 Dec 2020 22:10:03 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=b5OhexaH5aN6TtfX4J+kSR3CSpFw4fR+xXkwBPEhxtU=; b=MCaWVs3KuniIAvdvzQQofi7kys WiH5GwAGvDvnsPjAem19tILN8FR6PuR+ahIZV9WbhYxR3D4xb1ExCWEBSRypjzRmScOMnXyugGUjm WyUYrYntZu1fNviPMzzmJFthG3Ji2CUfqHB9j6bIYfNkiduPUi2cZhcmsgIfnlU2Df1x5yqvqX//q cZYGdqNkXyCk6PnULzVN3iw64IIySosndUae3N+2xMaUbEuBNGYvVBpUDAX5oDIiyPjudJDwxNnu2 HVyCdtvW3ruP/Mqt9q9JSsY8lyQX1K4EcjvEJKj44d+B/jsfwj3G+k0bpGaZDa7mrkTQL4OI+QriT My++Ogfg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kpUg1-0000Pz-3A; Wed, 16 Dec 2020 11:09:01 +0000 Received: from mga09.intel.com ([134.134.136.24]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kpUZ0-0004Oq-Lm for hostap@lists.infradead.org; Wed, 16 Dec 2020 11:01:49 +0000 IronPort-SDR: iawJOl7VdqmkdyIdmr6s0qVfB19pnR7DHkavftyHlyJKuDh9Q5IcuTlWago6c0Y7qlT/YnbeM3 aAt7bcDtZX/Q== X-IronPort-AV: E=McAfee;i="6000,8403,9836"; a="175192474" X-IronPort-AV: E=Sophos;i="5.78,424,1599548400"; d="scan'208";a="175192474" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Dec 2020 03:01:45 -0800 IronPort-SDR: 9otrqAGd35AiBoLb2+WAVPk95Wcj3ckSUI1o8PG70BWIqVtRUV63eqPqEMEZ8JLXqoESgOFato UpoZmmu2KzxQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.78,424,1599548400"; d="scan'208";a="412546001" Received: from jed01615.jer.intel.com ([10.12.190.15]) by orsmga001.jf.intel.com with ESMTP; 16 Dec 2020 03:01:44 -0800 From: Ilan Peer To: hostap@lists.infradead.org Subject: [PATCH 3/4] WPA: Support deriving KDK based on capabilities Date: Wed, 16 Dec 2020 13:01:39 +0200 Message-Id: <20201216110140.8440-4-ilan.peer@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201216110140.8440-1-ilan.peer@intel.com> References: <20201216110140.8440-1-ilan.peer@intel.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201216_060146_902613_87A99840 X-CRM114-Status: GOOD ( 18.43 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [134.134.136.24 listed in list.dnswl.org] 0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [134.134.136.24 listed in wl.mailspike.net] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Derive the KDK as part of PMK to PTK derivation if forced by configuration or in case both the local station and the AP declare support for secure LTF. Signed-off-by: Ilan Peer --- src/rsn_supp/wpa.c | 27 +++++++++++++++++++++------ src/rsn_supp/wpa.h | 2 +- src/rsn_supp/wpa_ft.c | 22 ++++++++++++++++++---- src/rsn_supp/wpa_i.h | 2 +- wpa_supplicant/wpas_glue.c | 2 +- 5 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index ed9aaae1a3..95f9e63765 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -579,7 +579,7 @@ static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr, const struct wpa_eapol_key *key, struct wpa_ptk *ptk) { const u8 *z = NULL; - size_t z_len = 0; + size_t z_len = 0, kdk_len; int akmp; #ifdef CONFIG_IEEE80211R @@ -603,11 +603,19 @@ static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr, akmp |= WPA_KEY_MGMT_PSK_SHA256; } #endif /* CONFIG_OWE */ + + if (sm->force_kdk_derivation || + (sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 && + sm->ap_rsnxe[3] & WLAN_RSNX_CAPAB_SECURE_LTF)) + kdk_len = WPA_KDK_MAX_LEN; + else + kdk_len = 0; + return wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion", sm->own_addr, sm->bssid, sm->snonce, key->key_nonce, ptk, akmp, sm->pairwise_cipher, z, z_len, - sm->kdk ? WPA_KDK_MAX_LEN : 0); + kdk_len); } @@ -3188,7 +3196,7 @@ void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config) sm->p2p = config->p2p; sm->wpa_rsc_relaxation = config->wpa_rsc_relaxation; sm->owe_ptk_workaround = config->owe_ptk_workaround; - sm->kdk = config->kdk; + sm->force_kdk_derivation = config->force_kdk_derivation; #ifdef CONFIG_FILS if (config->fils_cache_id) { sm->fils_cache_id_set = 1; @@ -3211,7 +3219,7 @@ void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config) sm->wpa_rsc_relaxation = 0; sm->owe_ptk_workaround = 0; sm->beacon_prot = 0; - sm->kdk = 0; + sm->force_kdk_derivation = 0; } } @@ -4134,7 +4142,7 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data, const u8 *g_sta = NULL; size_t g_sta_len = 0; const u8 *g_ap = NULL; - size_t g_ap_len = 0; + size_t g_ap_len = 0, kdk_len; struct wpabuf *pub = NULL; os_memcpy(sm->bssid, bssid, ETH_ALEN); @@ -4362,6 +4370,13 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data, goto fail; } + if (sm->force_kdk_derivation || + (sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 && + sm->ap_rsnxe[3] & WLAN_RSNX_CAPAB_SECURE_LTF)) + kdk_len = WPA_KDK_MAX_LEN; + else + kdk_len = 0; + if (fils_pmk_to_ptk(sm->pmk, sm->pmk_len, sm->own_addr, sm->bssid, sm->fils_nonce, sm->fils_anonce, dh_ss ? wpabuf_head(dh_ss) : NULL, @@ -4369,7 +4384,7 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data, &sm->ptk, ick, &ick_len, sm->key_mgmt, sm->pairwise_cipher, sm->fils_ft, &sm->fils_ft_len, - sm->kdk ? WPA_KDK_MAX_LEN : 0) < 0) { + kdk_len) < 0) { wpa_printf(MSG_DEBUG, "FILS: Failed to derive PTK"); goto fail; } diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index 2b181653eb..005d9f428e 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -132,7 +132,7 @@ struct rsn_supp_config { int owe_ptk_workaround; const u8 *fils_cache_id; int beacon_prot; - int kdk; + int force_kdk_derivation; }; #ifndef CONFIG_NO_WPA diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c index cbf3caeb01..d113fd9a20 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -35,7 +35,7 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr, const u8 *anonce = key->key_nonce; int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt); const u8 *mpmk; - size_t mpmk_len; + size_t mpmk_len, kdk_len; if (sm->xxkey_len > 0) { mpmk = sm->xxkey; @@ -65,10 +65,17 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr, wpa_ft_pasn_store_r1kh(sm, src_addr); #endif /* CONFIG_PASN*/ + if (sm->force_kdk_derivation || + (sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 && + sm->ap_rsnxe[3] & WLAN_RSNX_CAPAB_SECURE_LTF)) + kdk_len = WPA_KDK_MAX_LEN; + else + kdk_len = 0; + return wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, sm->snonce, anonce, sm->own_addr, sm->bssid, sm->pmk_r1_name, ptk, ptk_name, sm->key_mgmt, sm->pairwise_cipher, - sm->kdk ? WPA_KDK_MAX_LEN : 0); + kdk_len); } @@ -536,7 +543,7 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, int ret; const u8 *bssid; const u8 *kck; - size_t kck_len; + size_t kck_len, kdk_len; int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt); const u8 *anonce, *snonce; @@ -663,11 +670,18 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, wpa_ft_pasn_store_r1kh(sm, bssid); #endif /* CONFIG_PASN*/ + if (sm->force_kdk_derivation || + (sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 && + sm->ap_rsnxe[3] & WLAN_RSNX_CAPAB_SECURE_LTF)) + kdk_len = WPA_KDK_MAX_LEN; + else + kdk_len = 0; + if (wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, sm->snonce, anonce, sm->own_addr, bssid, sm->pmk_r1_name, &sm->ptk, ptk_name, sm->key_mgmt, sm->pairwise_cipher, - sm->kdk ? WPA_KDK_MAX_LEN : 0) < 0) + kdk_len) < 0) return -1; if (wpa_key_mgmt_fils(sm->key_mgmt)) { diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index 5f68282617..7ea1cd2dba 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -82,7 +82,7 @@ struct wpa_sm { * If set Key Derivation Key should be derived as part of PMK to * PTK derivation. */ - int kdk; + int force_kdk_derivation; u8 own_addr[ETH_ALEN]; const char *ifname; diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c index 80f04551d2..befd6d52d4 100644 --- a/wpa_supplicant/wpas_glue.c +++ b/wpa_supplicant/wpas_glue.c @@ -1476,7 +1476,7 @@ void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s, } #ifdef CONFIG_PASN #ifdef CONFIG_TESTING_OPTIONS - conf.kdk = wpa_s->conf->force_kdk_derivation; + conf.force_kdk_derivation = wpa_s->conf->force_kdk_derivation; #endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_PASN*/ wpa_sm_set_config(wpa_s->wpa, ssid ? &conf : NULL); From patchwork Wed Dec 16 11:01:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilan Peer X-Patchwork-Id: 1417070 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=I9EBGgt5; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Cwsq108v6z9sSs for ; Wed, 16 Dec 2020 22:10:05 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=Rosxi1LjFkVjSI3fzIkhbRLnynbLXeNWD4GtKZozyWk=; b=I9EBGgt5f9spbnqbvjAMJg8KZf fjQF7hPcj6JUig9zsHycT/dGvZ+Ioe9ctRjHKosWG6gRBmgeI6I2PkxczsUd+XedmxVEZVTizuvXo e+kl0NwWoY2IuxDJ215sG27P6BNgSk4AuMJtawumD9kVC51nelK+jBDchaQt2f2hQVPQTfzzrGTnN MLe7jDWN1Alc8lOtEYwTBoO9ixNmrV4TBubrxtsWv+wuOmrYkSJeL5M8Hr5J/j1wR/R8I57PcVTE6 m/lx8bY2YXcKYv90MN/iqt9mPSgzkKxurgk1DJQBsGdBVypRu7ZfWCxNt6YRUS0wIi9OojpN0PFWB uh3zFyHw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kpUgB-0000SC-Gu; Wed, 16 Dec 2020 11:09:11 +0000 Received: from mga09.intel.com ([134.134.136.24]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kpUZ1-0003up-Im for hostap@lists.infradead.org; Wed, 16 Dec 2020 11:01:49 +0000 IronPort-SDR: mI2elf+jgH8OlHm6HGDuusQ9frvi41d/e94a4ndMw4MbAmyNPr9T3VpT574hlLlLKCxdZa7bip SH6wmqtIX3Dg== X-IronPort-AV: E=McAfee;i="6000,8403,9836"; a="175192476" X-IronPort-AV: E=Sophos;i="5.78,424,1599548400"; d="scan'208";a="175192476" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Dec 2020 03:01:46 -0800 IronPort-SDR: RiZ9YqQnbe70LhDEGcIB+nKQyjPU63ZnqlkbqVY3ArnjF1KPg0LGW0a0vcOLzMoRl6h1pH6UN6 uT4VDIiNNMZw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.78,424,1599548400"; d="scan'208";a="412546021" Received: from jed01615.jer.intel.com ([10.12.190.15]) by orsmga001.jf.intel.com with ESMTP; 16 Dec 2020 03:01:45 -0800 From: Ilan Peer To: hostap@lists.infradead.org Subject: [PATCH 4/4] WPA_AUTH: Support deriving KDK based on capabilities Date: Wed, 16 Dec 2020 13:01:40 +0200 Message-Id: <20201216110140.8440-5-ilan.peer@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201216110140.8440-1-ilan.peer@intel.com> References: <20201216110140.8440-1-ilan.peer@intel.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201216_060147_813135_4B9A5CD3 X-CRM114-Status: GOOD ( 16.03 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [134.134.136.24 listed in list.dnswl.org] 0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [134.134.136.24 listed in wl.mailspike.net] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Derive the KDK as part of PMK to PTK derivation if forced by configuration or in case both the local AP and the peer station declare support for secure LTF. Signed-off-by: Ilan Peer --- src/ap/wpa_auth.c | 29 +++++++++++++++++++++-------- src/ap/wpa_auth.h | 2 +- src/ap/wpa_auth_ft.c | 14 ++++++++++---- src/ap/wpa_auth_glue.c | 2 +- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 73d61b9fd6..25f6c8d9fe 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -2278,9 +2278,17 @@ static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce, struct wpa_ptk *ptk, int force_sha256) { const u8 *z = NULL; - size_t z_len = 0; + size_t z_len = 0, kdk_len; int akmp; + if (sm->wpa_auth->conf.force_kdk_derivation || + (sm->wpa_auth->conf.secure_ltf && + sm->rsnxe && sm->rsnxe_len >= 4 && + sm->rsnxe[3] & WLAN_RSNX_CAPAB_SECURE_LTF)) + kdk_len = WPA_KDK_MAX_LEN; + else + kdk_len = 0; + #ifdef CONFIG_IEEE80211R_AP if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { if (sm->ft_completed) { @@ -2293,8 +2301,7 @@ static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce, ptk, ptk_name, sm->wpa_key_mgmt, sm->pairwise, - sm->wpa_auth->conf.kdk ? - WPA_KDK_MAX_LEN : 0); + kdk_len); } return wpa_auth_derive_ptk_ft(sm, ptk); } @@ -2312,8 +2319,7 @@ static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce, akmp |= WPA_KEY_MGMT_PSK_SHA256; return wpa_pmk_to_ptk(pmk, pmk_len, "Pairwise key expansion", sm->wpa_auth->addr, sm->addr, sm->ANonce, snonce, - ptk, akmp, sm->pairwise, z, z_len, - sm->wpa_auth->conf.kdk ? WPA_KDK_MAX_LEN : 0); + ptk, akmp, sm->pairwise, z, z_len, kdk_len); } @@ -2328,14 +2334,21 @@ int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk, size_t ick_len; int res; u8 fils_ft[FILS_FT_MAX_LEN]; - size_t fils_ft_len = 0; + size_t fils_ft_len = 0, kdk_len; + + if (sm->wpa_auth->conf.force_kdk_derivation || + (sm->wpa_auth->conf.secure_ltf && + sm->rsnxe && sm->rsnxe_len >= 4 && + sm->rsnxe[3] & WLAN_RSNX_CAPAB_SECURE_LTF)) + kdk_len = WPA_KDK_MAX_LEN; + else + kdk_len = 0; res = fils_pmk_to_ptk(pmk, pmk_len, sm->addr, sm->wpa_auth->addr, snonce, anonce, dhss, dhss_len, &sm->PTK, ick, &ick_len, sm->wpa_key_mgmt, sm->pairwise, - fils_ft, &fils_ft_len, - sm->wpa_auth->conf.kdk ? WPA_KDK_MAX_LEN : 0); + fils_ft, &fils_ft_len, kdk_len); if (res < 0) return res; sm->PTK_valid = true; diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index 129c65433d..ee9f721a00 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -272,7 +272,7 @@ struct wpa_auth_config { * If set Key Derivation Key should be derived as part of PMK to * PTK derivation. */ - int kdk; + int force_kdk_derivation; }; typedef enum { diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index 115a6fa2f3..6cdff65503 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -3066,7 +3066,7 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm, const u8 *identity, *radius_cui; size_t identity_len = 0, radius_cui_len = 0; int use_sha384; - size_t pmk_r1_len; + size_t pmk_r1_len, kdk_len; *resp_ies = NULL; *resp_ies_len = 0; @@ -3196,12 +3196,18 @@ pmk_r1_derived: wpa_hexdump(MSG_DEBUG, "FT: Generated ANonce", sm->ANonce, WPA_NONCE_LEN); + if (sm->wpa_auth->conf.force_kdk_derivation || + (sm->wpa_auth->conf.secure_ltf && + sm->rsnxe && sm->rsnxe_len >= 4 && + sm->rsnxe[3] & WLAN_RSNX_CAPAB_SECURE_LTF)) + kdk_len = WPA_KDK_MAX_LEN; + else + kdk_len = 0; + if (wpa_pmk_r1_to_ptk(pmk_r1, pmk_r1_len, sm->SNonce, sm->ANonce, sm->addr, sm->wpa_auth->addr, pmk_r1_name, &sm->PTK, ptk_name, sm->wpa_key_mgmt, - pairwise, - sm->wpa_auth->conf.kdk ? - WPA_KDK_MAX_LEN : 0) < 0) + pairwise, kdk_len) < 0) return WLAN_STATUS_UNSPECIFIED_FAILURE; sm->pairwise = pairwise; diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index 0e9b838127..74d2322ab4 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -210,7 +210,7 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf, #endif /* CONFIG_DPP2 */ #ifdef CONFIG_PASN #ifdef CONFIG_TESTING_OPTIONS - wconf->kdk = conf->force_kdk_derivation; + wconf->force_kdk_derivation = conf->force_kdk_derivation; #endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_PASN */ }