From patchwork Sun Aug 5 18:31:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Wetzel X-Patchwork-Id: 10556213 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 524E613AC for ; Sun, 5 Aug 2018 18:52:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2765D292EB for ; Sun, 5 Aug 2018 18:52:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0772E295D9; Sun, 5 Aug 2018 18:52:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6C21B292EB for ; Sun, 5 Aug 2018 18:52:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726556AbeHEU5d (ORCPT ); Sun, 5 Aug 2018 16:57:33 -0400 Received: from 8.mo69.mail-out.ovh.net ([46.105.56.233]:55971 "EHLO 8.mo69.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726484AbeHEU5c (ORCPT ); Sun, 5 Aug 2018 16:57:32 -0400 Received: from player692.ha.ovh.net (unknown [10.109.160.39]) by mo69.mail-out.ovh.net (Postfix) with ESMTP id 8FFCE1743D for ; Sun, 5 Aug 2018 20:32:07 +0200 (CEST) Received: from awhome.eu (p57B7EB85.dip0.t-ipconnect.de [87.183.235.133]) (Authenticated sender: postmaster@awhome.eu) by player692.ha.ovh.net (Postfix) with ESMTPSA id 51B90600099; Sun, 5 Aug 2018 20:32:06 +0200 (CEST) From: Alexander Wetzel DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=wetzel-home.de; s=wetzel-home; t=1533493918; bh=mxK0J+Bz7jq10gceLXmH220M2Fj5XEB8tViAN26qng8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=x9R7gU9e2UjS8TNNJ698ee8V5AgVHy/NHuhi3OBmsaK0ORNK7IenQ+lyJ0ZM+pD92 /Qz/sA2C2eVYypogV7v5QJUYt/2Y8ecaZnkw6ed6X6J/LEOizDblMqFcxYrNJ42syY nAo4CFl7Icq6MRnZYwYlDTSseKtTep4VgXJNOcL0= To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Alexander Wetzel Subject: [PATCH v5 2/3] mac80211: Define new driver callback replace_key Date: Sun, 5 Aug 2018 20:31:23 +0200 Message-Id: <20180805183124.29921-3-alexander@wetzel-home.de> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180805183124.29921-1-alexander@wetzel-home.de> References: <20180805183124.29921-1-alexander@wetzel-home.de> X-Ovh-Tracer-Id: 4802807529950747847 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtiedruddttddgudeftdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecu Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Define the new driver callback replace_key in mac80211 for future use. Drivers able to replace a in-use key should implement this new callback to allow mac80211 drivers to securely use PTK rekeying. On return of the function drivers must guarantee they: - Did not send out any frames for the key unencrypted during the replace, - will not send out packets queued to them prior to the call encrypted with the new key - and will no longer hand over any frames which were decrypted by the old key to mac80211 when not also handling PN (IV) in the driver. Packets handed over to the driver after the callback has returned are expected to be send out encrypted with the new key and retransmissions must either be dropped or continue to use the old key. Mac80211 will not hand over packets for the key being replaced while the callback is running. All other packets will still be handed over. If the driver can't handle that the driver is allowed to call functions like ieee80211_stop_queues from the callback. Signed-off-by: Alexander Wetzel --- include/net/mac80211.h | 15 +++++++++++++++ net/mac80211/driver-ops.h | 20 ++++++++++++++++++++ net/mac80211/main.c | 5 +++++ net/mac80211/trace.h | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 5790f55c241d..7d13cd10b7d7 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -3137,6 +3137,17 @@ enum ieee80211_reconfig_type { * Returns a negative error code if the key can't be added. * The callback can sleep. * + * @replace_key: Replace an exiting in use key with a new one while guaranteeing + * to not leak clear text packets. Implementing this callback will enable + * mac80211 to announce NL80211_EXT_FEATURE_ATOMIC_KEY_REPLACE. + * Packets already queued must not be send out encrypted with the new key + * and packets decoded with the old key must not be handed over to mac80211 + * when the driver is not checking IV/ICV itself once the callback has been + * completed. + * Mac80211 will log an error when asked to use replace a PTK key + * without replace_key but will still perform the then potentially + * insecure action via set_key for backward compatibility for now. + * * @update_tkip_key: See the section "Hardware crypto acceleration" * This callback will be called in the context of Rx. Called for drivers * which set IEEE80211_KEY_FLAG_TKIP_REQ_RX_P1_KEY. @@ -3585,6 +3596,10 @@ struct ieee80211_ops { int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ieee80211_key_conf *key); + int (*replace_key)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *old, + struct ieee80211_key_conf *new); void (*update_tkip_key)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_key_conf *conf, diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 8f6998091d26..ebd7f1463336 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -255,6 +255,26 @@ static inline int drv_set_key(struct ieee80211_local *local, return ret; } +static inline int drv_replace_key(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *old_key, + struct ieee80211_key_conf *new_key) +{ + int ret; + + might_sleep(); + + sdata = get_bss_sdata(sdata); + if (!check_sdata_in_driver(sdata)) + return -EIO; + + trace_drv_replace_key(local, sdata, sta, old_key, new_key); + ret = local->ops->replace_key(&local->hw, &sdata->vif, sta, old_key, new_key); + trace_drv_return_int(local, ret); + return ret; +} + static inline void drv_update_tkip_key(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, struct ieee80211_key_conf *conf, diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 4fb2709cb527..84cc8005c19a 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -572,9 +572,14 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT); } + if (ops->replace_key) + wiphy_ext_feature_set(wiphy, + NL80211_EXT_FEATURE_ATOMIC_KEY_REPLACE); + if (!ops->set_key) wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + if (ops->wake_tx_queue) wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_TXQS); diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 0ab69a1964f8..f93e00f1ae4d 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -603,6 +603,45 @@ TRACE_EVENT(drv_set_key, ) ); +TRACE_EVENT(drv_replace_key, + TP_PROTO(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *old_key, + struct ieee80211_key_conf *new_key), + + TP_ARGS(local, sdata, sta, old_key, new_key), + + TP_STRUCT__entry( + LOCAL_ENTRY + VIF_ENTRY + STA_ENTRY + KEY_ENTRY + __field(u32, cipher2) + __field(u8, hw_key_idx2) + __field(u8, flags2) + __field(s8, keyidx2) + ), + + TP_fast_assign( + LOCAL_ASSIGN; + VIF_ASSIGN; + STA_ASSIGN; + KEY_ASSIGN(old_key); + __entry->cipher2 = new_key->cipher; + __entry->flags2 = new_key->flags; + __entry->keyidx2 = new_key->keyidx; + __entry->hw_key_idx2 = new_key->hw_key_idx; + ), + + TP_printk( + LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT KEY_PR_FMT + " cipher2:0x%x, flags2=%#x, keyidx2=%d, hw_key_idx2=%d", + LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, KEY_PR_ARG, + __entry->cipher2, __entry->flags2, __entry->keyidx2, __entry->hw_key_idx2 + ) +); + TRACE_EVENT(drv_update_tkip_key, TP_PROTO(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata,