Explorar el Código

qcacmn: Support sae single pmk roaming BSS in scan

"WPA3-SAE Single PMK" is a feature by which STA can
complete SAE roaming to specific group of AP(s) using
single PMK. This is done with the help of advertising
vendor specific SAE single PMK IE in the beacon/probe.

When vendor specific sae single pmk IE (oui 0x00 40 96,
type 0x03) is present in the beacon/probe of AP then the
BSS supports WPA3-SAE roaming using Single PMK.

Add changes in scan module to parse the Vendor specific
SAE single PMK IE and copy it to the scan_entry ie_list.

Change-Id: I5b7096d1360c624ce1c47e56e8cad37adbdda1e3
CRs-Fixed: 2616099
Abhinav Kumar hace 5 años
padre
commit
90d227ce32

+ 29 - 1
umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -76,6 +76,19 @@
 #define OUI_TYPE_BITS           24
 #define MAX_ADAPTIVE_11R_IE_LEN 8
 
+/*
+ * sae single pmk vendor specific IE details
+ * Category     Data
+ * Type         0xDD
+ * Length       0x05
+ * OUI          0x00 40 96
+ * Type         0x03
+ * Data         Don’t care (EX, 0x05)
+ */
+#define SAE_SINGLE_PMK_OUI          0x964000
+#define SAE_SINGLE_PMK_TYPE         0x03
+#define MAX_SAE_SINGLE_PMK_IE_LEN   8
+
 /* Temporary vendor specific IE for 11n pre-standard interoperability */
 #define VENDOR_HT_OUI       0x00904c
 #define VENDOR_HT_CAP_ID    51
@@ -1508,6 +1521,21 @@ is_adaptive_11r_oui(uint8_t *frm)
 		((ADAPTIVE_11R_OUI_TYPE << OUI_TYPE_BITS) | ADAPTIVE_11R_OUI));
 }
 
+/**
+ * is_sae_single_pmk_oui() - Fun to check if vendor IE is sae single pmk OUI
+ * @frm: vendor IE pointer
+ *
+ * API to check if vendor IE is sae single pmk OUI
+ *
+ * Return: true if its sae single pmk OUI
+ */
+static inline bool
+is_sae_single_pmk_oui(uint8_t *frm)
+{
+	return (frm[1] > OUI_LENGTH) && (LE_READ_4(frm + 2) ==
+		((SAE_SINGLE_PMK_TYPE << OUI_TYPE_BITS) | SAE_SINGLE_PMK_OUI));
+}
+
 /**
  * wlan_parse_rsn_ie() - parse rsn ie
  * @rsn_ie: rsn ie ptr

+ 2 - 0
umac/scan/dispatcher/inc/wlan_scan_public_structs.h

@@ -159,6 +159,7 @@ struct element_info {
  * @mbo_oce: pointer to mbo/oce indication ie
  * @rnrie: reduced neighbor report IE
  * @adaptive_11r: pointer to adaptive 11r IE
+ * @single_pmk: Pointer to sae single pmk IE
  */
 struct ie_list {
 	uint8_t *tim;
@@ -210,6 +211,7 @@ struct ie_list {
 	uint8_t *rnrie;
 	uint8_t *extender;
 	uint8_t *adaptive_11r;
+	uint8_t *single_pmk;
 };
 
 enum scan_entry_connection_state {

+ 19 - 1
umac/scan/dispatcher/inc/wlan_scan_utils_api.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -708,6 +708,7 @@ util_scan_copy_beacon_data(struct scan_cache_entry *new_entry,
 	ie_lst->rnrie = conv_ptr(ie_lst->rnrie, old_ptr, new_ptr);
 	ie_lst->extender = conv_ptr(ie_lst->extender, old_ptr, new_ptr);
 	ie_lst->adaptive_11r = conv_ptr(ie_lst->adaptive_11r, old_ptr, new_ptr);
+	ie_lst->single_pmk = conv_ptr(ie_lst->single_pmk, old_ptr, new_ptr);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -858,6 +859,23 @@ util_scan_entry_adaptive_11r(struct scan_cache_entry *scan_entry)
 	return scan_entry->ie_list.adaptive_11r;
 }
 
+/**
+ * util_scan_entry_single_pmk()- function to read single pmk Vendor IE
+ * @scan_entry: scan entry
+ *
+ * API, function to read sae single pmk IE
+ *
+ * Return: true if single_pmk ie is present or false if ie is not present
+ */
+static inline bool
+util_scan_entry_single_pmk(struct scan_cache_entry *scan_entry)
+{
+	if (scan_entry->ie_list.single_pmk)
+		return true;
+
+	return false;
+}
+
 /**
  * util_scan_get_rsn_len()- function to read rsn IE length if present
  * @scan_entry: scan entry

+ 8 - 0
umac/scan/dispatcher/src/wlan_scan_utils_api.c

@@ -826,6 +826,14 @@ util_scan_parse_vendor_ie(struct scan_cache_entry *scan_params,
 
 		scan_params->ie_list.adaptive_11r = (uint8_t *)ie +
 						sizeof(struct ie_header);
+	} else if (is_sae_single_pmk_oui((uint8_t *)ie)) {
+		if ((ie->ie_len < OUI_LENGTH) ||
+		    (ie->ie_len > MAX_SAE_SINGLE_PMK_IE_LEN)) {
+			scm_debug("Invalid sae single pmk OUI");
+			return QDF_STATUS_E_INVAL;
+		}
+		scan_params->ie_list.single_pmk = (uint8_t *)ie +
+						sizeof(struct ie_header);
 	}
 	return QDF_STATUS_SUCCESS;
 }