From d8d18f187ae309d4a9777a96691cbb5bfd76937d Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Sirasanagandla Date: Thu, 8 Jun 2017 18:12:50 +0530 Subject: [PATCH] qcacmn: Add support to randomize probe req SA and Seq number qcacld-2.0 to qcacmn propagation Randomize probe request's source address and sequence number to improve user's privacy. Change-Id: I265f15476f1a23a268f159a44b6a3e4243fb9068 CRs-Fixed: 1105081 --- os_if/linux/scan/src/wlan_cfg80211_scan.c | 136 ++++++++++++++++++ .../obj_mgr/inc/wlan_objmgr_vdev_obj.h | 8 ++ .../obj_mgr/src/wlan_objmgr_vdev_obj.c | 23 +++ .../dispatcher/inc/wlan_scan_public_structs.h | 16 +++ wmi/inc/wmi_unified_param.h | 4 + wmi/src/wmi_unified_tlv.c | 38 +++++ 6 files changed, 225 insertions(+) diff --git a/os_if/linux/scan/src/wlan_cfg80211_scan.c b/os_if/linux/scan/src/wlan_cfg80211_scan.c index 683a6692d0b8..981f6ee3211a 100644 --- a/os_if/linux/scan/src/wlan_cfg80211_scan.c +++ b/os_if/linux/scan/src/wlan_cfg80211_scan.c @@ -59,6 +59,91 @@ static uint32_t hdd_config_sched_scan_start_delay( } #endif +#if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) +/** + * wlan_fill_scan_rand_attrs() - Populate the scan randomization attrs + * @vdev: pointer to objmgr vdev + * @flags: cfg80211 scan flags + * @mac_addr: random mac addr from cfg80211 + * @mac_addr_mask: mac addr mask from cfg80211 + * @randomize: output variable to check scan randomization status + * @addr: output variable to hold random addr + * @mask: output variable to hold mac mask + * + * Return: None + */ +static void wlan_fill_scan_rand_attrs(struct wlan_objmgr_vdev *vdev, + uint32_t flags, + uint8_t *mac_addr, + uint8_t *mac_addr_mask, + bool *randomize, + uint8_t *addr, + uint8_t *mask) +{ + if (!(flags & NL80211_SCAN_FLAG_RANDOM_ADDR)) + return; + + if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) + return; + + if (wlan_vdev_is_connected(vdev)) + return; + + *randomize = true; + memcpy(addr, mac_addr, QDF_MAC_ADDR_SIZE); + memcpy(mask, mac_addr_mask, QDF_MAC_ADDR_SIZE); + cfg80211_info("Random mac addr: %pM and Random mac mask: %pM", + addr, mask); +} + +/** + * wlan_scan_rand_attrs() - Wrapper function to fill scan random attrs + * @vdev: pointer to objmgr vdev + * @request: pointer to cfg80211 scan request + * @req: pointer to cmn module scan request + * + * This is a wrapper function which invokes wlan_fill_scan_rand_attrs() + * to fill random attributes of internal scan request with cfg80211_scan_request + * + * Return: None + */ +static void wlan_scan_rand_attrs(struct wlan_objmgr_vdev *vdev, + struct cfg80211_scan_request *request, + struct scan_start_request *req) +{ + bool *randomize = &req->scan_req.scan_random.randomize; + uint8_t *mac_addr = req->scan_req.scan_random.mac_addr; + uint8_t *mac_mask = req->scan_req.scan_random.mac_mask; + + wlan_fill_scan_rand_attrs(vdev, request->flags, request->mac_addr, + request->mac_addr_mask, randomize, mac_addr, + mac_mask); + if (!*randomize) + return; + + req->scan_req.scan_f_add_spoofed_mac_in_probe = true; + req->scan_req.scan_f_add_rand_seq_in_probe = true; +} +#else +/** + * wlan_scan_rand_attrs() - Wrapper function to fill scan random attrs + * @vdev: pointer to objmgr vdev + * @request: pointer to cfg80211 scan request + * @req: pointer to cmn module scan request + * + * This is a wrapper function which invokes wlan_fill_scan_rand_attrs() + * to fill random attributes of internal scan request with cfg80211_scan_request + * + * Return: None + */ +static void wlan_scan_rand_attrs(struct wlan_objmgr_vdev *vdev, + struct cfg80211_scan_request *request, + struct scan_start_request *req) +{ +} +#endif + #ifdef FEATURE_WLAN_SCAN_PNO #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) || \ defined(CFG80211_MULTI_SCAN_PLAN_BACKPORT)) @@ -223,6 +308,52 @@ static QDF_STATUS wlan_cfg80211_is_chan_ok_for_dnbs( } #endif +#if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) +/** + * wlan_pno_scan_rand_attr() - Wrapper function to fill sched scan random attrs + * @vdev: pointer to objmgr vdev + * @request: pointer to cfg80211 sched scan request + * @req: pointer to cmn module pno scan request + * + * This is a wrapper function which invokes wlan_fill_scan_rand_attrs() + * to fill random attributes of internal pno scan + * with cfg80211_sched_scan_request + * + * Return: None + */ +static void wlan_pno_scan_rand_attr(struct wlan_objmgr_vdev *vdev, + struct cfg80211_sched_scan_request *request, + struct pno_scan_req_params *req) +{ + bool *randomize = &req->scan_random.randomize; + uint8_t *mac_addr = req->scan_random.mac_addr; + uint8_t *mac_mask = req->scan_random.mac_mask; + + wlan_fill_scan_rand_attrs(vdev, request->flags, request->mac_addr, + request->mac_addr_mask, randomize, mac_addr, + mac_mask); +} +#else +/** + * wlan_pno_scan_rand_attr() - Wrapper function to fill sched scan random attrs + * @vdev: pointer to objmgr vdev + * @request: pointer to cfg80211 sched scan request + * @req: pointer to cmn module pno scan request + * + * This is a wrapper function which invokes wlan_fill_scan_rand_attrs() + * to fill random attributes of internal pno scan + * with cfg80211_sched_scan_request + * + * Return: None + */ +static void wlan_pno_scan_rand_attr(struct wlan_objmgr_vdev *vdev, + struct cfg80211_sched_scan_request *request, + struct pno_scan_req_params *req) +{ +} +#endif + int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_pdev *pdev, struct net_device *dev, struct cfg80211_sched_scan_request *request, @@ -388,6 +519,8 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_pdev *pdev, cfg80211_notice("Number of hidden networks being Configured = %d", request->n_ssids); + wlan_pno_scan_rand_attr(vdev, request, req); + /* * Before Kernel 4.4 * Driver gets only one time interval which is hard coded in @@ -1149,6 +1282,9 @@ int wlan_cfg80211_scan(struct wlan_objmgr_pdev *pdev, request->ie_len); } + if (!is_p2p_scan) + wlan_scan_rand_attrs(vdev, request, req); + if (request->flags & NL80211_SCAN_FLAG_FLUSH) ucfg_scan_flush_results(pdev, NULL); diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h index 581c1306467d..17ac88347c75 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h @@ -1447,4 +1447,12 @@ static inline uint16_t wlan_vdev_get_max_peer_count( { return vdev->vdev_objmgr.max_peer_count; } + +/** + * wlan_vdev_is_connected() - Check whether peer is associated or not + * @vdev: pointer to objmgr vdev + * + * Return: true in case success else false + */ +bool wlan_vdev_is_connected(struct wlan_objmgr_vdev *vdev); #endif /* _WLAN_OBJMGR_VDEV_OBJ_H_*/ diff --git a/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c b/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c index 70c5bcd9a5a8..f1732d9004b0 100644 --- a/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c +++ b/umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c @@ -794,3 +794,26 @@ void wlan_objmgr_vdev_release_ref(struct wlan_objmgr_vdev *vdev, return; } EXPORT_SYMBOL(wlan_objmgr_vdev_release_ref); + +bool wlan_vdev_is_connected(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_objmgr_peer *peer; + enum wlan_peer_state peer_state; + + wlan_vdev_obj_lock(vdev); + peer = wlan_vdev_get_bsspeer(vdev); + wlan_vdev_obj_unlock(vdev); + + if (!peer) + return false; + + wlan_peer_obj_lock(peer); + peer_state = wlan_peer_mlme_get_state(peer); + wlan_peer_obj_unlock(peer); + + if (peer_state != WLAN_ASSOC_STATE) + return false; + + return true; +} +EXPORT_SYMBOL(wlan_vdev_is_connected); diff --git a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h index 10d942afa2d5..0ad9e2e51906 100644 --- a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h +++ b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h @@ -467,6 +467,18 @@ enum scan_dwelltime_adaptive_mode { SCAN_DWELL_MODE_STATIC = 4 }; +/** + * struct scan_random_attr - holds scan randomization attrs + * @randomize: set to true for scan randomization + * @mac_addr: mac addr to be randomized + * @mac_mask: used to represent bits in mac_addr for randomization + */ +struct scan_random_attr { + bool randomize; + uint8_t mac_addr[QDF_MAC_ADDR_SIZE]; + uint8_t mac_mask[QDF_MAC_ADDR_SIZE]; +}; + /** * struct scan_req_params - start scan request parameter * @scan_id: scan id @@ -533,6 +545,7 @@ enum scan_dwelltime_adaptive_mode { * @chan_list: channel list * @ssid: ssid list * @bssid_list: Lisst of bssid to scan + * @scan_random: scan randomization params * @extraie: list of optional/vendor specific ie's to be added in probe requests * @htcap: htcap ie * @vhtcap: vhtcap ie @@ -611,6 +624,7 @@ struct scan_req_params { uint32_t chan_list[WLAN_SCAN_MAX_NUM_CHANNELS]; struct wlan_ssid ssid[WLAN_SCAN_MAX_NUM_SSID]; struct qdf_mac_addr bssid_list[WLAN_SCAN_MAX_NUM_BSSID]; + struct scan_random_attr scan_random; struct element_info extraie; struct element_info htcap; struct element_info vhtcap; @@ -882,6 +896,7 @@ struct pno_nw_type { * @channel_prediction_full_scan: periodic timer upon which a full scan needs * to be triggered. * @networks_list: Preferred network list + * @scan_random: scan randomization params * * E.g. * { fast_scan_period=120, fast_scan_max_cycles=2, @@ -904,6 +919,7 @@ struct pno_scan_req_params { enum scan_dwelltime_adaptive_mode adaptive_dwell_mode; uint32_t channel_prediction_full_scan; struct pno_nw_type networks_list[SCAN_PNO_MAX_SUPP_NETWORKS]; + struct scan_random_attr scan_random; }; /** diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index c9552e0b4749..bcaf61f0428a 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -1812,9 +1812,13 @@ struct rssi_monitor_param { /** * struct scan_mac_oui - oui paramters * @oui: oui parameters + * @vdev_id: interface id + * @enb_probe_req_sno_randomization: control probe req sequence no randomization */ struct scan_mac_oui { uint8_t oui[WMI_WIFI_SCANNING_MAC_OUI_LENGTH]; + uint32_t vdev_id; + bool enb_probe_req_sno_randomization; }; #define WMI_PASSPOINT_REALM_LEN 256 diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 01294e7ebb45..82090a452144 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -2157,6 +2157,23 @@ static inline void *get_pdev_wmi_handle(wmi_unified_t wmi_handle, uint8_t vdev_i return wmi_unified_get_pdev_handle(wmi_handle->soc, pdev_id); } +/** + * wmi_copy_scan_random_mac() - To copy scan randomization attrs to wmi buffer + * @mac: random mac addr + * @mask: random mac mask + * @mac_addr: wmi random mac + * @mac_mask: wmi random mac mask + * + * Return None. + */ +static inline +void wmi_copy_scan_random_mac(uint8_t *mac, uint8_t *mask, + wmi_mac_addr *mac_addr, wmi_mac_addr *mac_mask) +{ + WMI_CHAR_ARRAY_TO_MAC_ADDR(mac, mac_addr); + WMI_CHAR_ARRAY_TO_MAC_ADDR(mask, mac_mask); +} + /** * send_scan_start_cmd_tlv() - WMI scan start function * @param wmi_handle : handle to WMI. @@ -2241,6 +2258,12 @@ static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, WMI_LOGD("scan_ctrl_flags_ext = %x", cmd->scan_ctrl_flags_ext); + if (params->scan_random.randomize) + wmi_copy_scan_random_mac(params->scan_random.mac_addr, + params->scan_random.mac_mask, + &cmd->mac_addr, + &cmd->mac_mask); + buf_ptr += sizeof(*cmd); tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); for (i = 0; i < params->num_chan; ++i) @@ -5212,6 +5235,11 @@ static QDF_STATUS send_scan_probe_setoui_cmd_tlv(wmi_unified_t wmi_handle, WMI_LOGD("%s: wmi:oui received from hdd %08x", __func__, cmd->prob_req_oui); + cmd->vdev_id = psetoui->vdev_id; + cmd->flags = WMI_SCAN_PROBE_OUI_SPOOFED_MAC_IN_PROBE_REQ; + if (psetoui->enb_probe_req_sno_randomization) + cmd->flags |= WMI_SCAN_PROBE_OUI_RANDOM_SEQ_NO_IN_PROBE_REQ; + if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len, WMI_SCAN_PROB_REQ_OUI_CMDID)) { WMI_LOGE("%s: failed to send command", __func__); @@ -7253,6 +7281,16 @@ static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, cmd->fast_scan_period, cmd->slow_scan_period); WMI_LOGD("fast_scan_max_cycles: %d", cmd->fast_scan_max_cycles); + /* mac randomization attributes */ + if (pno->scan_random.randomize) { + cmd->flags |= WMI_NLO_CONFIG_SPOOFED_MAC_IN_PROBE_REQ | + WMI_NLO_CONFIG_RANDOM_SEQ_NO_IN_PROBE_REQ; + wmi_copy_scan_random_mac(pno->scan_random.mac_addr, + pno->scan_random.mac_mask, + &cmd->mac_addr, + &cmd->mac_mask); + } + buf_ptr += sizeof(wmi_nlo_config_cmd_fixed_param); cmd->no_of_ssids = QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS);