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.anan...@intel.com> --- lib/librte_ipsec/esp_inb.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) 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; } -- 2.17.1