From 686abd96f4e99c7a3569ab1b18d1b1a06eb1de47 Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Sirasanagandla Date: Thu, 8 Jun 2017 18:09:01 +0530 Subject: [PATCH] qcacld-3.0: Add support to randomize probe req SA and Seq number qcacld-2.0 to qcacld-3.0 propagation Randomize probe request's source address and sequence number to improve user's privacy. Change-Id: Ic367ce4578e65faf49e8092f0f8cce057eead728 CRs-Fixed: 1085995 --- core/cds/inc/cds_api.h | 17 ++++++++ core/hdd/src/wlan_hdd_cfg80211.c | 25 +++++++++++- core/hdd/src/wlan_hdd_scan.c | 69 ++++++++++++++++++++++++++++++++ core/mac/inc/sir_api.h | 2 + core/wma/src/wma_scan_roam.c | 4 ++ 5 files changed, 115 insertions(+), 2 deletions(-) diff --git a/core/cds/inc/cds_api.h b/core/cds/inc/cds_api.h index d54a7c388f95..ab2a3a2d2e45 100644 --- a/core/cds/inc/cds_api.h +++ b/core/cds/inc/cds_api.h @@ -405,4 +405,21 @@ void cds_print_htc_credit_history(uint32_t count, qdf_abstract_print * print, void *print_priv); #endif +/** + * cds_is_group_addr() - checks whether addr is multi cast + * @mac_addr: address to be checked for multicast + * + * Check if the input mac addr is multicast addr + * + * Return: true if multicast addr else false + */ +static inline +bool cds_is_group_addr(uint8_t *mac_addr) +{ + if (mac_addr[0] & 0x01) + return true; + else + return false; +} + #endif /* if !defined __CDS_API_H */ diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index e7b4d99b270c..543be84bebb8 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -2765,6 +2765,8 @@ __wlan_hdd_cfg80211_set_scanning_mac_oui(struct wiphy *wiphy, QDF_STATUS status; int ret; int len; + struct net_device *ndev = wdev->netdev; + hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(ndev); ENTER_DEV(wdev->netdev); @@ -2812,8 +2814,13 @@ __wlan_hdd_cfg80211_set_scanning_mac_oui(struct wiphy *wiphy, nla_memcpy(&pReqMsg->oui[0], tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI], sizeof(pReqMsg->oui)); - hdd_debug("Oui (%02x:%02x:%02x)", pReqMsg->oui[0], - pReqMsg->oui[1], pReqMsg->oui[2]); + + /* populate pReqMsg for mac addr randomization */ + pReqMsg->vdev_id = adapter->sessionId; + pReqMsg->enb_probe_req_sno_randomization = true; + + hdd_debug("Oui (%02x:%02x:%02x), vdev_id = %d", pReqMsg->oui[0], + pReqMsg->oui[1], pReqMsg->oui[2], pReqMsg->vdev_id); status = sme_set_scanning_mac_oui(pHddCtx->hHal, pReqMsg); if (!QDF_IS_STATUS_SUCCESS(status)) { hdd_err("sme_set_scanning_mac_oui failed(err=%d)", status); @@ -11417,6 +11424,19 @@ int wlan_hdd_cfg80211_update_band(hdd_context_t *hdd_ctx, struct wiphy *wiphy, return 0; } +#if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) +static void wlan_hdd_cfg80211_scan_randomization_init(struct wiphy *wiphy) +{ + wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; + wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR; +} +#else +static void wlan_hdd_cfg80211_scan_randomization_init(struct wiphy *wiphy) +{ +} +#endif + #define WLAN_HDD_MAX_NUM_CSA_COUNTERS 2 /* * FUNCTION: wlan_hdd_cfg80211_init @@ -11643,6 +11663,7 @@ int wlan_hdd_cfg80211_init(struct device *dev, hdd_add_channel_switch_support(&wiphy->flags); wiphy->max_num_csa_counters = WLAN_HDD_MAX_NUM_CSA_COUNTERS; + wlan_hdd_cfg80211_scan_randomization_init(wiphy); EXIT(); return 0; diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c index 7607a90dc5f7..8f2ece70ae84 100644 --- a/core/hdd/src/wlan_hdd_scan.c +++ b/core/hdd/src/wlan_hdd_scan.c @@ -1477,6 +1477,72 @@ static void hdd_process_vendor_acs_response(hdd_adapter_t *adapter) } } +#if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) +/** + * wlan_hdd_vendor_scan_random_attr() - check and fill scan randomization attrs + * @wiphy: Pointer to wiphy + * @request: Pointer to scan request + * @wdev: Pointer to wireless device + * @tb: Pointer to nl attributes + * + * This function is invoked to check whether vendor scan needs + * probe req source addr, if so populates mac_addr and mac_addr_mask + * in scan request with nl attrs. + * + * Return: 0 - on success, negative value on failure + */ +static int wlan_hdd_vendor_scan_random_attr(struct wiphy *wiphy, + struct cfg80211_scan_request *request, + struct wireless_dev *wdev, + struct nlattr **tb) +{ + uint32_t i; + int32_t len = QDF_MAC_ADDR_SIZE; + + if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)) + return 0; + + if (!(wiphy->features & NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR) || + (wdev->current_bss)) { + hdd_err("SCAN RANDOMIZATION not supported"); + return -EOPNOTSUPP; + } + + if (!tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC] || + !tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]) + return -EINVAL; + + if ((nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC]) != len) || + (nla_len(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]) != len)) + return -EINVAL; + + qdf_mem_copy(request->mac_addr, + nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC]), len); + + qdf_mem_copy(request->mac_addr_mask, + nla_data(tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]), len); + + /* avoid configure on multicast address */ + if (!cds_is_group_addr(request->mac_addr_mask) || + cds_is_group_addr(request->mac_addr)) + return -EINVAL; + + for (i = 0; i < ETH_ALEN; i++) + request->mac_addr[i] &= request->mac_addr_mask[i]; + + return 0; +} +#else +static int wlan_hdd_vendor_scan_random_attr(struct wiphy *wiphy, + struct cfg80211_scan_request *request, + struct wireless_dev *wdev, + struct nlattr **tb) +{ + return 0; +} +#endif + static const struct nla_policy scan_policy[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1] = { [QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS] = {.type = NLA_U32}, @@ -1659,6 +1725,9 @@ static int __wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy, hdd_err("LOW PRIORITY SCAN not supported"); goto error; } + + if (wlan_hdd_vendor_scan_random_attr(wiphy, request, wdev, tb)) + goto error; } if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_BSSID]) { diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 07f63a0d4220..9136e111f226 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -4764,6 +4764,8 @@ struct rso_cmd_status { typedef struct { uint8_t oui[WIFI_SCANNING_MAC_OUI_LENGTH]; + uint32_t vdev_id; + bool enb_probe_req_sno_randomization; } tSirScanMacOui, *tpSirScanMacOui; enum { diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 057e78714f2e..1f951a38ee24 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -5254,6 +5254,10 @@ QDF_STATUS wma_scan_probe_setoui(tp_wma_handle wma, tSirScanMacOui *psetoui) qdf_mem_copy(set_oui.oui, psetoui->oui, WMI_WIFI_SCANNING_MAC_OUI_LENGTH); + set_oui.vdev_id = psetoui->vdev_id; + set_oui.enb_probe_req_sno_randomization = + psetoui->enb_probe_req_sno_randomization; + return wmi_unified_scan_probe_setoui_cmd(wma->wmi_handle, &set_oui); }