[6/6] ipsec: reorder packet check for esp inbound

Message ID 1551381661-21078-7-git-send-email-konstantin.ananyev@intel.com (mailing list archive)
State Superseded, archived
Delegated to: akhil goyal
Headers
Series Few small improvements for ipsec library |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Ananyev, Konstantin Feb. 28, 2019, 7:21 p.m. UTC
  Right now check for packet length and padding is done inside cop_prepare().
It makes sense to have all necessary checks in one place at early stage:
inside pkt_prepare().
That allows to simplify (and later hopefully) optimize cop_prepare() part.

Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
 lib/librte_ipsec/esp_inb.c | 30 ++++++++++++++----------------
 1 file changed, 14 insertions(+), 16 deletions(-)
  

Patch

diff --git a/lib/librte_ipsec/esp_inb.c b/lib/librte_ipsec/esp_inb.c
index 562185ebe..d479af8ea 100644
--- a/lib/librte_ipsec/esp_inb.c
+++ b/lib/librte_ipsec/esp_inb.c
@@ -26,11 +26,6 @@  inb_cop_prepare(struct rte_crypto_op *cop,
 	struct rte_crypto_sym_op *sop;
 	struct aead_gcm_iv *gcm;
 	uint64_t *ivc, *ivp;
-	uint32_t clen;
-
-	clen = plen - sa->ctp.cipher.length;
-	if ((int32_t)clen < 0 || (clen & (sa->pad_align - 1)) != 0)
-		return -EINVAL;
 
 	/* fill sym op fields */
 	sop = cop->sym;
@@ -38,7 +33,7 @@  inb_cop_prepare(struct rte_crypto_op *cop,
 	/* AEAD (AES_GCM) case */
 	if (sa->aad_len != 0) {
 		sop->aead.data.offset = pofs + sa->ctp.cipher.offset;
-		sop->aead.data.length = clen;
+		sop->aead.data.length = plen - sa->ctp.cipher.length;
 		sop->aead.digest.data = icv->va;
 		sop->aead.digest.phys_addr = icv->pa;
 		sop->aead.aad.data = icv->va + sa->icv_len;
@@ -53,7 +48,7 @@  inb_cop_prepare(struct rte_crypto_op *cop,
 	/* CRYPT+AUTH case */
 	} else {
 		sop->cipher.data.offset = pofs + sa->ctp.cipher.offset;
-		sop->cipher.data.length = clen;
+		sop->cipher.data.length = plen - sa->ctp.cipher.length;
 		sop->auth.data.offset = pofs + sa->ctp.auth.offset;
 		sop->auth.data.length = plen - sa->ctp.auth.length;
 		sop->auth.digest.data = icv->va;
@@ -101,7 +96,7 @@  inb_pkt_prepare(const struct rte_ipsec_sa *sa, const struct replay_sqn *rsn,
 {
 	int32_t rc;
 	uint64_t sqn;
-	uint32_t icv_ofs, plen;
+	uint32_t clen, icv_ofs, plen;
 	struct rte_mbuf *ml;
 	struct esp_hdr *esph;
 
@@ -128,6 +123,11 @@  inb_pkt_prepare(const struct rte_ipsec_sa *sa, const struct replay_sqn *rsn,
 	ml = rte_pktmbuf_lastseg(mb);
 	icv_ofs = ml->data_len - sa->icv_len + sa->sqh_len;
 
+	/* check that packet has a valid length */
+	clen = plen - sa->ctp.cipher.length;
+	if ((int32_t)clen < 0 || (clen & (sa->pad_align - 1)) != 0)
+		return -EBADMSG;
+
 	/* we have to allocate space for AAD somewhere,
 	 * right now - just use free trailing space at the last segment.
 	 * Would probably be more convenient to reserve space for AAD
@@ -170,21 +170,19 @@  esp_inb_pkt_prepare(const struct rte_ipsec_session *ss, struct rte_mbuf *mb[],
 		rc = inb_pkt_prepare(sa, rsn, mb[i], hl, &icv);
 		if (rc >= 0) {
 			lksd_none_cop_prepare(cop[k], cs, mb[i]);
-			rc = inb_cop_prepare(cop[k], sa, mb[i], &icv, hl, rc);
-		}
-
-		k += (rc == 0);
-		if (rc != 0) {
+			inb_cop_prepare(cop[k], sa, mb[i], &icv, hl, rc);
+			k++;
+		} else
 			dr[i - k] = i;
-			rte_errno = -rc;
-		}
 	}
 
 	rsn_release(sa, rsn);
 
 	/* copy not prepared mbufs beyond good ones */
-	if (k != num && k != 0)
+	if (k != num && k != 0) {
 		mbuf_bad_move(mb, dr, num, num - k);
+		rte_errno = EBADMSG;
+	}
 
 	return k;
 }