ソースを参照

qcacld-3.0: Modify check to ensure consecutive PN for frags

Modify check to ensure packet number is consecutive for
fragments and drop the fragments if the check fails.

Change-Id: Ica24f65aff65ca58bb010c876f27964b5b2bae6a
CRs-Fixed: 2860242
Yeshwanth Sriram Guntuka 4 年 前
コミット
5deab77487

+ 7 - 1
core/dp/txrx/ol_rx_defrag.c

@@ -700,7 +700,13 @@ ol_rx_defrag(ol_txrx_pdev_handle pdev,
 	while (cur) {
 		tmp_next = qdf_nbuf_next(cur);
 		qdf_nbuf_set_next(cur, NULL);
-		if (!ol_rx_pn_check_base(vdev, peer, tid, cur)) {
+		/*
+		 * Strict PN check between the first fragment of the current
+		 * frame and the last fragment of the previous frame is not
+		 * necessary.
+		 */
+		if (!ol_rx_pn_check_base(vdev, peer, tid, cur,
+					 (cur == frag_list) ? false : true)) {
 			/* PN check failed,discard frags */
 			if (prev) {
 				qdf_nbuf_set_next(prev, NULL);

+ 24 - 13
core/dp/txrx/ol_rx_pn.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013-2017, 2019-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011, 2013-2017, 2019-2021 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
@@ -37,25 +37,36 @@
 	} while (0)
 
 int ol_rx_pn_cmp24(union htt_rx_pn_t *new_pn,
-		   union htt_rx_pn_t *old_pn, int is_unicast, int opmode)
+		   union htt_rx_pn_t *old_pn, int is_unicast, int opmode,
+		   bool strict_chk)
 {
-	int rc = ((new_pn->pn24 & 0xffffff) <= (old_pn->pn24 & 0xffffff));
-	return rc;
+	if (strict_chk)
+		return ((new_pn->pn24 & 0xffffff) - (old_pn->pn24 & 0xffffff)
+			!= 1);
+	else
+		return ((new_pn->pn24 & 0xffffff) <= (old_pn->pn24 & 0xffffff));
 }
 
 int ol_rx_pn_cmp48(union htt_rx_pn_t *new_pn,
-		   union htt_rx_pn_t *old_pn, int is_unicast, int opmode)
+		   union htt_rx_pn_t *old_pn, int is_unicast, int opmode,
+		   bool strict_chk)
 {
-	int rc = ((new_pn->pn48 & 0xffffffffffffULL) <=
-		  (old_pn->pn48 & 0xffffffffffffULL));
-	return rc;
+	if (strict_chk)
+		return ((new_pn->pn48 & 0xffffffffffffULL) -
+			(old_pn->pn48 & 0xffffffffffffULL) != 1);
+	else
+		return ((new_pn->pn48 & 0xffffffffffffULL) <=
+			(old_pn->pn48 & 0xffffffffffffULL));
 }
 
 int ol_rx_pn_wapi_cmp(union htt_rx_pn_t *new_pn,
-		      union htt_rx_pn_t *old_pn, int is_unicast, int opmode)
+		      union htt_rx_pn_t *old_pn, int is_unicast, int opmode,
+		      bool strict_chk)
 {
 	int pn_is_replay = 0;
 
+	/* TODO Strick check for WAPI is not implemented*/
+
 	if (new_pn->pn128[1] == old_pn->pn128[1])
 		pn_is_replay = (new_pn->pn128[0] <= old_pn->pn128[0]);
 	else
@@ -73,7 +84,7 @@ int ol_rx_pn_wapi_cmp(union htt_rx_pn_t *new_pn,
 qdf_nbuf_t
 ol_rx_pn_check_base(struct ol_txrx_vdev_t *vdev,
 		    struct ol_txrx_peer_t *peer,
-		    unsigned int tid, qdf_nbuf_t msdu_list)
+		    unsigned int tid, qdf_nbuf_t msdu_list, bool strict_chk)
 {
 	struct ol_txrx_pdev_t *pdev = vdev->pdev;
 	union htt_rx_pn_t *last_pn;
@@ -132,7 +143,7 @@ ol_rx_pn_check_base(struct ol_txrx_vdev_t *vdev,
 			pn_is_replay =
 				pdev->rx_pn[peer->security[index].sec_type].
 				cmp(&new_pn, last_pn, index == txrx_sec_ucast,
-				    vdev->opmode);
+				    vdev->opmode, strict_chk);
 		} else {
 			last_pn_valid = peer->tids_last_pn_valid[tid] = 1;
 		}
@@ -249,7 +260,7 @@ ol_rx_pn_check(struct ol_txrx_vdev_t *vdev,
 	       struct ol_txrx_peer_t *peer, unsigned int tid,
 	       qdf_nbuf_t msdu_list)
 {
-	msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list);
+	msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list, false);
 	ol_rx_fwd_check(vdev, peer, tid, msdu_list);
 }
 
@@ -258,7 +269,7 @@ ol_rx_pn_check_only(struct ol_txrx_vdev_t *vdev,
 		    struct ol_txrx_peer_t *peer,
 		    unsigned int tid, qdf_nbuf_t msdu_list)
 {
-	msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list);
+	msdu_list = ol_rx_pn_check_base(vdev, peer, tid, msdu_list, false);
 	ol_rx_deliver(vdev, peer, tid, msdu_list);
 }
 

+ 9 - 5
core/dp/txrx/ol_rx_pn.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011, 2014-2017, 2021 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
@@ -24,13 +24,16 @@
 #include <ol_txrx_api.h>        /* ol_txrx_peer_t, etc. */
 
 int ol_rx_pn_cmp24(union htt_rx_pn_t *new_pn,
-		   union htt_rx_pn_t *old_pn, int is_unicast, int opmode);
+		   union htt_rx_pn_t *old_pn, int is_unicast, int opmode,
+		   bool strict_chk);
 
 int ol_rx_pn_cmp48(union htt_rx_pn_t *new_pn,
-		   union htt_rx_pn_t *old_pn, int is_unicast, int opmode);
+		   union htt_rx_pn_t *old_pn, int is_unicast, int opmode,
+		   bool strict_chk);
 
 int ol_rx_pn_wapi_cmp(union htt_rx_pn_t *new_pn,
-		      union htt_rx_pn_t *old_pn, int is_unicast, int opmode);
+		      union htt_rx_pn_t *old_pn, int is_unicast, int opmode,
+		      bool strict_chk);
 
 /**
  * @brief If applicable, check the Packet Number to detect replays.
@@ -87,11 +90,12 @@ ol_rx_pn_check_only(struct ol_txrx_vdev_t *vdev,
  * @param tid - which TID within the peer the rx frames belong to
  * @param msdu_list - NULL-terminated list of MSDUs to perform PN check on
  *      (if PN check is applicable, i.e. PN length > 0)
+ * @param strick_chk - if PN consecutive stric check is needed or not
  * @return list of netbufs that didn't fail the PN check
  */
 qdf_nbuf_t
 ol_rx_pn_check_base(struct ol_txrx_vdev_t *vdev,
 		    struct ol_txrx_peer_t *peer,
-		    unsigned int tid, qdf_nbuf_t msdu_list);
+		    unsigned int tid, qdf_nbuf_t msdu_list, bool strict_chk);
 
 #endif /* _OL_RX_PN_H_ */

+ 18 - 0
core/dp/txrx/ol_txrx.c

@@ -1437,14 +1437,32 @@ ol_txrx_pdev_post_attach(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
 	 */
 	qdf_mem_zero(&pdev->rx_pn[0], sizeof(pdev->rx_pn));
 
+	/* WEP: 24-bit PN */
+	pdev->rx_pn[htt_sec_type_wep40].len =
+		pdev->rx_pn[htt_sec_type_wep104].len =
+			pdev->rx_pn[htt_sec_type_wep128].len = 24;
+
+	pdev->rx_pn[htt_sec_type_wep40].cmp =
+		pdev->rx_pn[htt_sec_type_wep104].cmp =
+			pdev->rx_pn[htt_sec_type_wep128].cmp = ol_rx_pn_cmp24;
+
 	/* TKIP: 48-bit TSC, CCMP: 48-bit PN */
 	pdev->rx_pn[htt_sec_type_tkip].len =
 		pdev->rx_pn[htt_sec_type_tkip_nomic].len =
 			pdev->rx_pn[htt_sec_type_aes_ccmp].len = 48;
+
+	pdev->rx_pn[htt_sec_type_aes_ccmp_256].len =
+		pdev->rx_pn[htt_sec_type_aes_gcmp].len =
+			pdev->rx_pn[htt_sec_type_aes_gcmp_256].len = 48;
+
 	pdev->rx_pn[htt_sec_type_tkip].cmp =
 		pdev->rx_pn[htt_sec_type_tkip_nomic].cmp =
 			pdev->rx_pn[htt_sec_type_aes_ccmp].cmp = ol_rx_pn_cmp48;
 
+	pdev->rx_pn[htt_sec_type_aes_ccmp_256].cmp =
+		pdev->rx_pn[htt_sec_type_aes_gcmp].cmp =
+		    pdev->rx_pn[htt_sec_type_aes_gcmp_256].cmp = ol_rx_pn_cmp48;
+
 	/* WAPI: 128-bit PN */
 	pdev->rx_pn[htt_sec_type_wapi].len = 128;
 	pdev->rx_pn[htt_sec_type_wapi].cmp = ol_rx_pn_wapi_cmp;

+ 1 - 1
core/dp/txrx/ol_txrx_types.h

@@ -831,7 +831,7 @@ struct ol_txrx_pdev_t {
 	struct {
 		int (*cmp)(union htt_rx_pn_t *new,
 			   union htt_rx_pn_t *old,
-			   int is_unicast, int opmode);
+			   int is_unicast, int opmode, bool strict_chk);
 		int len;
 	} rx_pn[htt_num_sec_types];