Browse Source

qcacld-3.0: Add WAPI IE in probe response for WAPI SAP mode support

The WAPI IE is not included in the probe response in the driver for
the WAPI SAP mode, and will cause the external WAPI STA does not
trigger the WAPI connection to the WAPI SAP if configured as WAPI
SAP mode.

Change-Id: I9212e0fe9d495e8300a2bfbed65d398e0fb27170
CRs-Fixed: 3148702
Ke Huang 3 years ago
parent
commit
8de43bd6e4

+ 33 - 0
core/hdd/inc/wlan_hdd_assoc.h

@@ -538,4 +538,37 @@ wlan_hdd_ft_set_key_delay(struct wlan_objmgr_vdev *vdev)
 }
 #endif
 
+#ifdef FEATURE_WLAN_WAPI
+/**
+ * hdd_translate_wapi_to_csr_auth_type() - Translate WAPI to CSR auth type
+ * @auth_suite: auth suite
+ *
+ * Return: enum csr_akm_type enumeration
+ */
+enum csr_akm_type hdd_translate_wapi_to_csr_auth_type(uint8_t auth_suite[4]);
+
+/**
+ * hdd_translate_wapi_to_csr_encryption_type() -
+ *	Translate WAPI to CSR encryption type
+ * @cipher_suite: cipher suite
+ *
+ * Return: eCsrEncryptionType enumeration
+ */
+eCsrEncryptionType
+hdd_translate_wapi_to_csr_encryption_type(uint8_t cipher_suite[4]);
+#else
+enum csr_akm_type hdd_translate_wapi_to_csr_auth_type(uint8_t auth_suite[4])
+{
+	return eCSR_AUTH_TYPE_UNKNOWN;
+}
+
+eCsrEncryptionType
+hdd_translate_wapi_to_csr_encryption_type(uint8_t cipher_suite[4])
+{
+	return eCSR_AUTH_TYPE_UNKNOWN;
+}
+#endif
+
+
+
 #endif

+ 38 - 0
core/hdd/src/wlan_hdd_assoc.c

@@ -163,6 +163,14 @@ uint8_t ccp_rsn_oui_90[HDD_RSN_OUI_SIZE] = {0x00, 0x0F, 0xAC, 0x09};
 static const
 u8 ccp_rsn_oui_13[HDD_RSN_OUI_SIZE] = {0x50, 0x6F, 0x9A, 0x01};
 
+#ifdef FEATURE_WLAN_WAPI
+#define HDD_WAPI_OUI_SIZE 4
+/* WPI-SMS4 */
+uint8_t ccp_wapi_oui01[HDD_WAPI_OUI_SIZE] = { 0x00, 0x14, 0x72, 0x01 };
+/* WAI-PSK */
+uint8_t ccp_wapi_oui02[HDD_WAPI_OUI_SIZE] = { 0x00, 0x14, 0x72, 0x02 };
+#endif  /* FEATURE_WLAN_WAPI */
+
 /* Offset where the EID-Len-IE, start. */
 #define ASSOC_RSP_IES_OFFSET 6  /* Capability(2) + AID(2) + Status Code(2) */
 #define ASSOC_REQ_IES_OFFSET 4  /* Capability(2) + LI(2) */
@@ -2384,6 +2392,36 @@ hdd_translate_wpa_to_csr_encryption_type(uint8_t cipher_suite[4])
 	return cipher_type;
 }
 
+#ifdef FEATURE_WLAN_WAPI
+enum csr_akm_type hdd_translate_wapi_to_csr_auth_type(uint8_t auth_suite[4])
+{
+	enum csr_akm_type auth_type;
+
+	if (memcmp(auth_suite, ccp_wapi_oui01, 4) == 0)
+		auth_type = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
+	else if (memcmp(auth_suite, ccp_wapi_oui02, 4) == 0)
+		auth_type = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
+	else
+		auth_type = eCSR_AUTH_TYPE_UNKNOWN;
+
+	return auth_type;
+}
+
+eCsrEncryptionType
+hdd_translate_wapi_to_csr_encryption_type(uint8_t cipher_suite[4])
+{
+	eCsrEncryptionType cipher_type;
+
+	if (memcmp(cipher_suite, ccp_wapi_oui01, 4) == 0 ||
+		   memcmp(cipher_suite, ccp_wapi_oui02, 4) == 0)
+		cipher_type = eCSR_ENCRYPT_TYPE_WPI;
+	else
+		cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
+
+	return cipher_type;
+}
+#endif /* FEATURE_WLAN_WAPI */
+
 #ifdef WLAN_FEATURE_FILS_SK
 bool hdd_is_fils_connection(struct hdd_context *hdd_ctx,
 			    struct hdd_adapter *adapter)

+ 50 - 1
core/hdd/src/wlan_hdd_hostapd.c

@@ -2992,6 +2992,7 @@ static int hdd_softap_unpack_ie(mac_handle_t mac_handle,
 	uint16_t rsn_ie_len, i;
 	tDot11fIERSN dot11_rsn_ie = {0};
 	tDot11fIEWPA dot11_wpa_ie = {0};
+	tDot11fIEWAPI dot11_wapi_ie = {0};
 
 	if (!mac_handle) {
 		hdd_err("NULL mac Handle");
@@ -3083,6 +3084,47 @@ static int hdd_softap_unpack_ie(mac_handle_t mac_handle,
 								 multicast_cipher);
 		*mfp_capable = false;
 		*mfp_required = false;
+	} else if (gen_ie[0] == DOT11F_EID_WAPI) {
+		/* Validity checks */
+		if ((gen_ie_len < DOT11F_IE_WAPI_MIN_LEN) ||
+		    (gen_ie_len > DOT11F_IE_WAPI_MAX_LEN))
+			return QDF_STATUS_E_FAILURE;
+
+		/* Skip past the EID byte and length byte */
+		rsn_ie = gen_ie + 2;
+		rsn_ie_len = gen_ie_len - 2;
+		/* Unpack the WAPI IE */
+		memset(&dot11_wapi_ie, 0, sizeof(tDot11fIEWPA));
+		ret = dot11f_unpack_ie_wapi(MAC_CONTEXT(mac_handle),
+					    rsn_ie, rsn_ie_len,
+					    &dot11_wapi_ie, false);
+		if (DOT11F_FAILED(ret)) {
+			hdd_err("unpack failed, 0x%x", ret);
+			return -EINVAL;
+		}
+		/* Copy out the encryption and authentication types */
+		hdd_debug("WAPI unicast cipher suite count: %d akm count: %d",
+			  dot11_wapi_ie.unicast_cipher_suite_count,
+			  dot11_wapi_ie.akm_suite_count);
+		/*
+		 * Translate akms in akm suite
+		 */
+		for (i = 0; i < dot11_wapi_ie.akm_suite_count; i++)
+			akm_list->authType[i] =
+				hdd_translate_wapi_to_csr_auth_type(
+						dot11_wapi_ie.akm_suites[i]);
+
+		akm_list->numEntries = dot11_wapi_ie.akm_suite_count;
+		/* dot11_wapi_ie.akm_suite_count */
+		*encrypt_type =
+			hdd_translate_wapi_to_csr_encryption_type(
+				dot11_wapi_ie.unicast_cipher_suites[0]);
+		/* dot11_wapi_ie.unicast_cipher_count */
+		*mc_encrypt_type =
+			hdd_translate_wapi_to_csr_encryption_type(
+				dot11_wapi_ie.multicast_cipher_suite);
+		*mfp_capable = false;
+		*mfp_required = false;
 	} else {
 		hdd_err("gen_ie[0]: %d", gen_ie[0]);
 		return QDF_STATUS_E_FAILURE;
@@ -5995,13 +6037,20 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter,
 	memset(&config->RSNWPAReqIE[0], 0, sizeof(config->RSNWPAReqIE));
 	ie = wlan_get_ie_ptr_from_eid(WLAN_EID_RSN, beacon->tail,
 				      beacon->tail_len);
+	/* the RSN and WAPI are not coexisting, so we can check the
+	 * WAPI IE if the RSN IE is not set.
+	 */
+	if (!ie)
+		ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_WAPI, beacon->tail,
+					      beacon->tail_len);
+
 	if (ie && ie[1]) {
 		config->RSNWPAReqIELength = ie[1] + 2;
 		if (config->RSNWPAReqIELength < sizeof(config->RSNWPAReqIE))
 			memcpy(&config->RSNWPAReqIE[0], ie,
 			       config->RSNWPAReqIELength);
 		else
-			hdd_err("RSNWPA IE MAX Length exceeded; length =%d",
+			hdd_err("RSN/WPA/WAPI IE MAX Length exceeded; length =%d",
 			       config->RSNWPAReqIELength);
 		/* The actual processing may eventually be more extensive than
 		 * this. Right now, just consume any PMKIDs that are sent in

+ 3 - 2
core/hdd/src/wlan_hdd_softap_tx_rx.c

@@ -611,8 +611,9 @@ static QDF_STATUS hdd_softap_validate_peer_state(struct hdd_adapter *adapter,
 	}
 
 	if (peer_state == OL_TXRX_PEER_STATE_CONN) {
-		if (ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X) {
-			hdd_sapd_debug_rl("NON-EAPOL packet in non-Authenticated state");
+		if (ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X &&
+			!IS_HDD_ETHERTYPE_WAI(skb)) {
+			hdd_sapd_debug_rl("NON EAPOL/WAPI pkt in non-Auth");
 			return QDF_STATUS_E_FAILURE;
 		}
 	}

+ 17 - 4
core/mac/src/include/parser_api.h

@@ -919,15 +919,28 @@ populate_dot11f_rsn_opaque(struct mac_context *mac,
 		tpSirRSNie pRsnIe, tDot11fIERSNOpaque *pDot11f);
 
 #if defined(FEATURE_WLAN_WAPI)
-
 QDF_STATUS
 populate_dot11f_wapi(struct mac_context *mac,
-		tpSirRSNie pRsnIe, tDot11fIEWAPI *pDot11f);
+		     tpSirRSNie pRsnIe, tDot11fIEWAPI *pDot11f);
 
 QDF_STATUS populate_dot11f_wapi_opaque(struct mac_context *mac,
-					tpSirRSNie pRsnIe,
-					tDot11fIEWAPIOpaque *pDot11f);
+				       tpSirRSNie pRsnIe,
+				       tDot11fIEWAPIOpaque *pDot11f);
+#else
+static inline QDF_STATUS
+populate_dot11f_wapi(struct mac_context *mac,
+		     tpSirRSNie pRsnIe, tDot11fIEWAPI *pDot11f)
+{
+	return QDF_STATUS_SUCCESS;
+}
 
+static inline QDF_STATUS
+populate_dot11f_wapi_opaque(struct mac_context *mac,
+			    tpSirRSNie pRsnIe,
+			    tDot11fIEWAPIOpaque *pDot11f)
+{
+	return QDF_STATUS_SUCCESS;
+}
 #endif /* defined(FEATURE_WLAN_WAPI) */
 
 /* / Populate a tDot11fIESSID given a tSirMacSSid */

+ 10 - 0
core/mac/src/pe/sch/sch_beacon_gen.c

@@ -767,6 +767,8 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess
 		populate_dot11f_rsn_opaque(mac_ctx,
 					   &session->pLimStartBssReq->rsnIE,
 					   &bcn_2->RSNOpaque);
+		populate_dot11f_wapi(mac_ctx, &session->pLimStartBssReq->rsnIE,
+				     &bcn_2->WAPI);
 	}
 
 	if (session->limWmeEnabled)
@@ -1148,6 +1150,14 @@ void lim_update_probe_rsp_template_ie_bitmap_beacon2(struct mac_context *mac,
 			     sizeof(beacon2->RSNOpaque));
 	}
 
+	/* WAPI */
+	if (beacon2->WAPI.present) {
+		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap, WLAN_ELEMID_WAPI);
+		qdf_mem_copy((void *)&prb_rsp->WAPI,
+			     (void *)&beacon2->WAPI,
+			     sizeof(beacon2->WAPI));
+	}
+
 	/* EDCA Parameter set */
 	if (beacon2->EDCAParamSet.present) {
 		set_probe_rsp_ie_bitmap(DefProbeRspIeBitmap,