Kaynağa Gözat

qcacmn: Add WAPI support in crypto convergence

Added WAPI support in crypto convergence.
Included WAPI IE parsing and adding WAPI IE.

CRs-Fixed: 2073813

Change-Id: I23cecb45d0a2282fffba5c2e95ad8592801c0818
Ashok Ponnaiah 7 yıl önce
ebeveyn
işleme
26e6be4b76

+ 27 - 0
umac/cmn_services/crypto/inc/wlan_crypto_global_api.h

@@ -305,6 +305,33 @@ uint8_t *wlan_crypto_build_wpaie(struct wlan_crypto_params *,
 uint8_t *wlan_crypto_build_rsnie(struct wlan_crypto_params *,
 					uint8_t *iebuf);
 
+/**
+ * wlan_crypto_wapiie_check - called by mlme to check the wapiie
+ *
+ *
+ * @crypto params: crypto params
+ * @iebuf: ie buffer
+ *
+ * This function gets called by mlme to check the contents of wapi is
+ * matching with given crypto params
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS wlan_crypto_wapiie_check(struct wlan_crypto_params *crypto_params,
+					uint8_t *frm);
+
+/**
+ * wlan_crypto_build_wapiie - called by mlme to build wapi ie
+ *
+ * @vdev: vdev
+ * @iebuf: ie buffer
+ *
+ * This function gets called by mlme to build wapi ie from given vdev
+ *
+ * Return: end of buffer
+ */
+uint8_t *wlan_crypto_build_wapiie(struct wlan_objmgr_vdev *vdev,
+					uint8_t *iebuf);
 /**
  * wlan_crypto_rsn_info - check is given params matching with vdev params.
  *

+ 8 - 3
umac/cmn_services/crypto/src/wlan_crypto_def_i.h

@@ -201,7 +201,9 @@ static inline void wlan_crypto_put_be64(u8 *a, u64 val)
 	do {frm[0] = (v) & 0xff; frm[1] = (v) >> 8; frm += 2; } while (0)
 
 #define	WLAN_CRYPTO_ADDSELECTOR(frm, sel) \
-	do {qdf_mem_copy(frm, (uint8_t *)sel, OUI_SIZE); \
+	do { \
+		uint32_t value = sel;\
+		qdf_mem_copy(frm, (uint8_t *)&value, OUI_SIZE); \
 	frm += OUI_SIZE; } while (0)
 
 #define WLAN_CRYPTO_SELECTOR(a, b, c, d) \
@@ -212,6 +214,9 @@ static inline void wlan_crypto_put_be64(u8 *a, u64 val)
 
 #define WPA_TYPE_OUI     WLAN_CRYPTO_SELECTOR(0x00, 0x50, 0xf2, 1)
 
+#define WLAN_CRYPTO_WAPI_IE_LEN      20
+#define WLAN_CRYPTO_WAPI_SMS4_CIPHER 0x01
+
 #define WPA_AUTH_KEY_MGMT_NONE \
 				WLAN_CRYPTO_SELECTOR(0x00, 0x50, 0xf2, 0)
 #define WPA_AUTH_KEY_MGMT_UNSPEC_802_1X \
@@ -312,7 +317,7 @@ static inline void wlan_crypto_put_be64(u8 *a, u64 val)
 #define UCIPHER_IS_GCMP256(_param) \
 		HAS_UCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_AES_GCM_256)
 #define UCIPHER_IS_SMS4(_param)    \
-		HAS_UCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_WAPI)
+		HAS_UCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_WAPI_SMS4)
 
 #define RESET_MCAST_CIPHERS(_param)   ((_param)->mcastcipherset = 0)
 #define SET_MCAST_CIPHER(_param, _c)  ((_param)->mcastcipherset |= (1<<(_c)))
@@ -336,7 +341,7 @@ static inline void wlan_crypto_put_be64(u8 *a, u64 val)
 #define MCIPHER_IS_GCMP256(_param) \
 		HAS_MCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_AES_GCM_256)
 #define MCIPHER_IS_SMS4(_param)    \
-		HAS_MCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_WAPI)
+		HAS_MCAST_CIPHER((_param), WLAN_CRYPTO_CIPHER_WAPI_SMS4)
 
 #define RESET_MGMT_CIPHERS(_param)   ((_param)->mgmtcipherset = 0)
 #define SET_MGMT_CIPHER(_param, _c)  ((_param)->mgmtcipherset |= (1<<(_c)))

+ 193 - 0
umac/cmn_services/crypto/src/wlan_crypto_global_api.c

@@ -2130,6 +2130,199 @@ bool wlan_crypto_rsn_info(struct wlan_objmgr_vdev *vdev,
 	return true;
 }
 
+/*
+ * Convert an WAPI CIPHER suite to to an internal code.
+ */
+static int32_t wlan_crypto_wapi_suite_to_cipher(uint8_t *sel)
+{
+	uint32_t w = LE_READ_4(sel);
+	int32_t status = -1;
+
+	switch (w) {
+	case (WLAN_WAPI_SEL(WLAN_CRYPTO_WAPI_SMS4_CIPHER)):
+		return WLAN_CRYPTO_CIPHER_WAPI_SMS4;
+	}
+
+	return status;
+}
+
+/*
+ * Convert an WAPI key management/authentication algorithm
+ * to an internal code.
+ */
+static int32_t wlan_crypto_wapi_keymgmt(u_int8_t *sel)
+{
+	uint32_t w = LE_READ_4(sel);
+	int32_t status = -1;
+
+	switch (w) {
+	case (WLAN_WAPI_SEL(WLAN_WAI_PSK)):
+		return WLAN_CRYPTO_KEY_MGMT_WAPI_PSK;
+	case (WLAN_WAPI_SEL(WLAN_WAI_CERT_OR_SMS4)):
+		return WLAN_CRYPTO_KEY_MGMT_WAPI_CERT;
+	}
+
+	return status;
+}
+/**
+ * wlan_crypto_wapiie_check - called by mlme to check the wapiie
+ *
+ *
+ * @crypto params: crypto params
+ * @iebuf: ie buffer
+ *
+ * This function gets called by mlme to check the contents of wapi is
+ * matching with given crypto params
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS wlan_crypto_wapiie_check(struct wlan_crypto_params *crypto_params,
+					uint8_t *frm)
+{
+	uint8_t len = frm[1];
+	int32_t w;
+	int n;
+
+	/*
+	 * Check the length once for fixed parts: OUI, type,
+	 * version, mcast cipher, and 2 selector counts.
+	 * Other, variable-length data, must be checked separately.
+	 */
+	RESET_AUTHMODE(crypto_params);
+	SET_AUTHMODE(crypto_params, WLAN_CRYPTO_AUTH_WAPI);
+
+	if (len < WLAN_CRYPTO_WAPI_IE_LEN)
+		return QDF_STATUS_E_INVAL;
+
+
+	frm += 2;
+
+	w = LE_READ_2(frm);
+	frm += 2, len -= 2;
+	if (w != WAPI_VERSION)
+		return QDF_STATUS_E_INVAL;
+
+	n = LE_READ_2(frm);
+	frm += 2, len -= 2;
+	if (len < n*4+2)
+		return QDF_STATUS_E_INVAL;
+
+	RESET_KEY_MGMT(crypto_params);
+	for (; n > 0; n--) {
+		w = wlan_crypto_wapi_keymgmt(frm);
+		if (w < 0)
+			return QDF_STATUS_E_INVAL;
+
+		SET_KEY_MGMT(crypto_params, w);
+		frm += 4, len -= 4;
+	}
+
+	/* unicast ciphers */
+	n = LE_READ_2(frm);
+	frm += 2, len -= 2;
+	if (len < n*4+2)
+		return QDF_STATUS_E_INVAL;
+
+	RESET_UCAST_CIPHERS(crypto_params);
+	for (; n > 0; n--) {
+		w = wlan_crypto_wapi_suite_to_cipher(frm);
+		if (w < 0)
+			return QDF_STATUS_E_INVAL;
+		SET_UCAST_CIPHER(crypto_params, w);
+		frm += 4, len -= 4;
+	}
+
+	if (!crypto_params->ucastcipherset)
+		return QDF_STATUS_E_INVAL;
+
+	/* multicast/group cipher */
+	RESET_MCAST_CIPHERS(crypto_params);
+	w = wlan_crypto_wapi_suite_to_cipher(frm);
+
+	if (w < 0)
+		return QDF_STATUS_E_INVAL;
+
+	SET_MCAST_CIPHER(crypto_params, w);
+	frm += 4, len -= 4;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlan_crypto_build_wapiie - called by mlme to build wapi ie
+ *
+ * @vdev: vdev
+ * @iebuf: ie buffer
+ *
+ * This function gets called by mlme to build wapi ie from given vdev
+ *
+ * Return: end of buffer
+ */
+uint8_t *wlan_crypto_build_wapiie(struct wlan_objmgr_vdev *vdev,
+				uint8_t *iebuf)
+{
+	uint8_t *frm;
+	uint8_t *selcnt;
+	struct wlan_crypto_comp_priv *crypto_priv;
+	struct wlan_crypto_params *crypto_params;
+
+	frm = iebuf;
+	if (!frm) {
+		qdf_print("%s[%d] ie buffer NULL\n", __func__, __LINE__);
+		return NULL;
+	}
+
+	crypto_params = wlan_crypto_vdev_get_comp_params(vdev, &crypto_priv);
+
+	if (!crypto_params) {
+		qdf_print("%s[%d] crypto_params NULL\n", __func__, __LINE__);
+		return NULL;
+	}
+
+	*frm++ = WLAN_ELEMID_WAPI;
+	*frm++ = 0;
+
+	WLAN_CRYPTO_ADDSHORT(frm, WAPI_VERSION);
+
+	/* authenticator selector list */
+	selcnt = frm;
+	WLAN_CRYPTO_ADDSHORT(frm, 0);
+
+	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_WAPI_PSK)) {
+		selcnt[0]++;
+		WLAN_CRYPTO_ADDSELECTOR(frm,
+				WLAN_WAPI_SEL(WLAN_WAI_PSK));
+	}
+
+	if (HAS_KEY_MGMT(crypto_params, WLAN_CRYPTO_KEY_MGMT_WAPI_CERT)) {
+		selcnt[0]++;
+		WLAN_CRYPTO_ADDSELECTOR(frm,
+				WLAN_WAPI_SEL(WLAN_WAI_CERT_OR_SMS4));
+	}
+
+	/* unicast cipher list */
+	selcnt = frm;
+	WLAN_CRYPTO_ADDSHORT(frm, 0);
+
+	if (UCIPHER_IS_SMS4(crypto_params)) {
+		selcnt[0]++;
+		WLAN_CRYPTO_ADDSELECTOR(frm,
+				WLAN_WAPI_SEL(WLAN_CRYPTO_WAPI_SMS4_CIPHER));
+	}
+
+	WLAN_CRYPTO_ADDSELECTOR(frm,
+				WLAN_WAPI_SEL(WLAN_CRYPTO_WAPI_SMS4_CIPHER));
+
+	/* optional capabilities */
+	WLAN_CRYPTO_ADDSHORT(frm, crypto_params->rsn_caps);
+
+	/* calculate element length */
+	iebuf[1] = frm - iebuf - 2;
+
+	return frm;
+
+}
+
 /**
  * wlan_crypto_pn_check - called by data patch for PN check
  *