]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: cfg80211: validate cipher suite for NAN Data keys
authorDaniel Gabay <daniel.gabay@intel.com>
Wed, 15 Apr 2026 15:35:55 +0000 (18:35 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 28 Apr 2026 07:31:12 +0000 (09:31 +0200)
Per Wi-Fi Aware v4.0 section 7.1.2, NAN Data interfaces shall only
use CCMP-128 or GCMP-256 for frame protection. Enforce this in
cfg80211_validate_key_settings() by passing the wdev down to it.

Signed-off-by: Daniel Gabay <daniel.gabay@intel.com>
Reviewed-by: Ilan Peer <ilan.peer@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260415183550.14a422ac52fd.I486ae7188bc60e44503ecccc99af6ae3a31d16b8@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/wireless/core.h
net/wireless/nl80211.c
net/wireless/util.c
net/wireless/wext-compat.c

index ae2d56d3ad9083e66b13d0483a310c5a8b8771d3..0e6f9bd4ba1b80b18017db9c855ac8fe238ff400 100644 (file)
@@ -3,7 +3,7 @@
  * Wireless configuration interface internals.
  *
  * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
- * Copyright (C) 2018-2025 Intel Corporation
+ * Copyright (C) 2018-2026 Intel Corporation
  */
 #ifndef __NET_WIRELESS_CORE_H
 #define __NET_WIRELESS_CORE_H
@@ -446,6 +446,7 @@ bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher);
 bool cfg80211_valid_key_idx(struct cfg80211_registered_device *rdev,
                            int key_idx, bool pairwise);
 int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
+                                  struct wireless_dev *wdev,
                                   struct key_params *params, int key_idx,
                                   bool pairwise, const u8 *mac_addr);
 void __cfg80211_scan_done(struct wiphy *wiphy, struct wiphy_work *wk);
index b870456623fb3cd6fc19ddaa68a464fac4dafe9e..cf236307cca9c5b355747f0b2f02d3bfdbc91a00 100644 (file)
@@ -1733,6 +1733,7 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
 
 static struct cfg80211_cached_keys *
 nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
+                      struct wireless_dev *wdev,
                       struct genl_info *info, bool *no_ht)
 {
        struct nlattr *keys = info->attrs[NL80211_ATTR_KEYS];
@@ -1782,7 +1783,7 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
                                goto error;
                } else if (parse.defmgmt)
                        goto error;
-               err = cfg80211_validate_key_settings(rdev, &parse.p,
+               err = cfg80211_validate_key_settings(rdev, wdev, &parse.p,
                                                     parse.idx, false, NULL);
                if (err)
                        goto error;
@@ -5407,7 +5408,7 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
        if (!rdev->ops->add_key)
                return -EOPNOTSUPP;
 
-       if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
+       if (cfg80211_validate_key_settings(rdev, wdev, &key.p, key.idx,
                                           key.type == NL80211_KEYTYPE_PAIRWISE,
                                           mac_addr)) {
                GENL_SET_ERR_MSG(info, "key setting validation failed");
@@ -13227,7 +13228,8 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
        if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
                bool no_ht = false;
 
-               connkeys = nl80211_parse_connkeys(rdev, info, &no_ht);
+               connkeys = nl80211_parse_connkeys(rdev, dev->ieee80211_ptr,
+                                                 info, &no_ht);
                if (IS_ERR(connkeys))
                        return PTR_ERR(connkeys);
 
@@ -13669,7 +13671,8 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
        }
 
        if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
-               connkeys = nl80211_parse_connkeys(rdev, info, NULL);
+               connkeys = nl80211_parse_connkeys(rdev, dev->ieee80211_ptr,
+                                                 info, NULL);
                if (IS_ERR(connkeys))
                        return PTR_ERR(connkeys);
        }
index cff5a1bd95cc4907f21122c31cf2d0e216aa198f..95ae06e94f10c6effca20e37c0f105b8fccf3b06 100644 (file)
@@ -284,6 +284,7 @@ bool cfg80211_valid_key_idx(struct cfg80211_registered_device *rdev,
 }
 
 int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
+                                  struct wireless_dev *wdev,
                                   struct key_params *params, int key_idx,
                                   bool pairwise, const u8 *mac_addr)
 {
@@ -344,6 +345,15 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
                break;
        }
 
+       /*
+        * Per Wi-Fi Aware v4.0 section 7.1.2, NAN Data interfaces
+        * shall only use CCMP-128 or GCMP-256.
+        */
+       if (wdev->iftype == NL80211_IFTYPE_NAN_DATA &&
+           params->cipher != WLAN_CIPHER_SUITE_CCMP &&
+           params->cipher != WLAN_CIPHER_SUITE_GCMP_256)
+               return -EINVAL;
+
        switch (params->cipher) {
        case WLAN_CIPHER_SUITE_WEP40:
                if (params->key_len != WLAN_KEY_LEN_WEP40)
index 22d9d9bae8f58ae03992acb1cb9ca07955d8003d..28bc996c143709690374152c3693e5a84be7ef3d 100644 (file)
@@ -489,7 +489,8 @@ static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
        if (addr)
                tx_key = false;
 
-       if (cfg80211_validate_key_settings(rdev, params, idx, pairwise, addr))
+       if (cfg80211_validate_key_settings(rdev, wdev, params, idx,
+                                          pairwise, addr))
                return -EINVAL;
 
        err = 0;