All of lore.kernel.org
 help / color / mirror / Atom feed
From: Fan Zhang <roy.fan.zhang@intel.com>
To: dev@dpdk.org
Cc: akhil.goyal@nxp.com, konstantin.ananyev@intel.com,
	roy.fan.zhang@intel.com
Subject: [PATCH v3 1/4] ipsec: add AES-CTR algorithm support
Date: Mon, 25 Feb 2019 12:07:42 +0000	[thread overview]
Message-ID: <20190225120745.61836-2-roy.fan.zhang@intel.com> (raw)
In-Reply-To: <20190225120745.61836-1-roy.fan.zhang@intel.com>

This patch adds AES-CTR cipher algorithm support to ipsec
library.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 lib/librte_ipsec/crypto.h |  17 ++++++
 lib/librte_ipsec/sa.c     | 133 ++++++++++++++++++++++++++++++++++++++--------
 lib/librte_ipsec/sa.h     |  18 +++++++
 3 files changed, 147 insertions(+), 21 deletions(-)

diff --git a/lib/librte_ipsec/crypto.h b/lib/librte_ipsec/crypto.h
index b5f264831..4f551e39c 100644
--- a/lib/librte_ipsec/crypto.h
+++ b/lib/librte_ipsec/crypto.h
@@ -11,6 +11,16 @@
  * by ipsec library.
  */
 
+/*
+ * AES-CTR counter block format.
+ */
+
+struct aesctr_cnt_blk {
+	uint32_t nonce;
+	uint64_t iv;
+	uint32_t cnt;
+} __attribute__((packed));
+
  /*
   * AES-GCM devices have some specific requirements for IV and AAD formats.
   * Ideally that to be done by the driver itself.
@@ -41,6 +51,13 @@ struct gcm_esph_iv {
 	uint64_t iv;
 } __attribute__((packed));
 
+static inline void
+aes_ctr_cnt_blk_fill(struct aesctr_cnt_blk *ctr, uint64_t iv, uint32_t nonce)
+{
+	ctr->nonce = nonce;
+	ctr->iv = iv;
+	ctr->cnt = rte_cpu_to_be_32(1);
+}
 
 static inline void
 aead_gcm_iv_fill(struct aead_gcm_iv *gcm, uint64_t iv, uint32_t salt)
diff --git a/lib/librte_ipsec/sa.c b/lib/librte_ipsec/sa.c
index 5f55c2a4e..e34dd320a 100644
--- a/lib/librte_ipsec/sa.c
+++ b/lib/librte_ipsec/sa.c
@@ -219,18 +219,28 @@ esp_inb_tun_init(struct rte_ipsec_sa *sa, const struct rte_ipsec_sa_prm *prm)
 static void
 esp_outb_init(struct rte_ipsec_sa *sa, uint32_t hlen)
 {
+	uint8_t algo_type;
+
 	sa->sqn.outb.raw = 1;
 
 	/* these params may differ with new algorithms support */
 	sa->ctp.auth.offset = hlen;
 	sa->ctp.auth.length = sizeof(struct esp_hdr) + sa->iv_len + sa->sqh_len;
-	if (sa->aad_len != 0) {
+
+	algo_type = sa->algo_type;
+
+	switch (algo_type) {
+	case ALGO_TYPE_AES_GCM:
+	case ALGO_TYPE_AES_CTR:
+	case ALGO_TYPE_NULL:
 		sa->ctp.cipher.offset = hlen + sizeof(struct esp_hdr) +
 			sa->iv_len;
 		sa->ctp.cipher.length = 0;
-	} else {
+		break;
+	case ALGO_TYPE_AES_CBC:
 		sa->ctp.cipher.offset = sa->hdr_len + sizeof(struct esp_hdr);
 		sa->ctp.cipher.length = sa->iv_len;
+		break;
 	}
 }
 
@@ -259,26 +269,47 @@ esp_sa_init(struct rte_ipsec_sa *sa, const struct rte_ipsec_sa_prm *prm,
 				RTE_IPSEC_SATP_MODE_MASK;
 
 	if (cxf->aead != NULL) {
-		/* RFC 4106 */
-		if (cxf->aead->algo != RTE_CRYPTO_AEAD_AES_GCM)
+		switch (cxf->aead->algo) {
+		case RTE_CRYPTO_AEAD_AES_GCM:
+			/* RFC 4106 */
+			sa->aad_len = sizeof(struct aead_gcm_aad);
+			sa->icv_len = cxf->aead->digest_length;
+			sa->iv_ofs = cxf->aead->iv.offset;
+			sa->iv_len = sizeof(uint64_t);
+			sa->pad_align = IPSEC_PAD_AES_GCM;
+			sa->algo_type = ALGO_TYPE_AES_GCM;
+			break;
+		default:
 			return -EINVAL;
-		sa->aad_len = sizeof(struct aead_gcm_aad);
-		sa->icv_len = cxf->aead->digest_length;
-		sa->iv_ofs = cxf->aead->iv.offset;
-		sa->iv_len = sizeof(uint64_t);
-		sa->pad_align = IPSEC_PAD_AES_GCM;
+		}
 	} else {
 		sa->icv_len = cxf->auth->digest_length;
 		sa->iv_ofs = cxf->cipher->iv.offset;
 		sa->sqh_len = IS_ESN(sa) ? sizeof(uint32_t) : 0;
-		if (cxf->cipher->algo == RTE_CRYPTO_CIPHER_NULL) {
+
+		switch (cxf->cipher->algo) {
+		case RTE_CRYPTO_CIPHER_NULL:
 			sa->pad_align = IPSEC_PAD_NULL;
 			sa->iv_len = 0;
-		} else if (cxf->cipher->algo == RTE_CRYPTO_CIPHER_AES_CBC) {
+			sa->algo_type = ALGO_TYPE_NULL;
+			break;
+
+		case RTE_CRYPTO_CIPHER_AES_CBC:
 			sa->pad_align = IPSEC_PAD_AES_CBC;
 			sa->iv_len = IPSEC_MAX_IV_SIZE;
-		} else
+			sa->algo_type = ALGO_TYPE_AES_CBC;
+			break;
+
+		case RTE_CRYPTO_CIPHER_AES_CTR:
+			/* RFC 3686 */
+			sa->pad_align = IPSEC_PAD_AES_CTR;
+			sa->iv_len = IPSEC_AES_CTR_IV_SIZE;
+			sa->algo_type = ALGO_TYPE_AES_CTR;
+			break;
+
+		default:
 			return -EINVAL;
+		}
 	}
 
 	sa->udata = prm->userdata;
@@ -438,12 +469,15 @@ esp_outb_cop_prepare(struct rte_crypto_op *cop,
 {
 	struct rte_crypto_sym_op *sop;
 	struct aead_gcm_iv *gcm;
+	struct aesctr_cnt_blk *ctr;
+	uint8_t algo_type = sa->algo_type;
 
 	/* fill sym op fields */
 	sop = cop->sym;
 
-	/* AEAD (AES_GCM) case */
-	if (sa->aad_len != 0) {
+	switch (algo_type) {
+	case ALGO_TYPE_AES_GCM:
+		/* AEAD (AES_GCM) case */
 		sop->aead.data.offset = sa->ctp.cipher.offset + hlen;
 		sop->aead.data.length = sa->ctp.cipher.length + plen;
 		sop->aead.digest.data = icv->va;
@@ -455,14 +489,40 @@ esp_outb_cop_prepare(struct rte_crypto_op *cop,
 		gcm = rte_crypto_op_ctod_offset(cop, struct aead_gcm_iv *,
 			sa->iv_ofs);
 		aead_gcm_iv_fill(gcm, ivp[0], sa->salt);
-	/* CRYPT+AUTH case */
-	} else {
+		break;
+	case ALGO_TYPE_AES_CBC:
+		/* Cipher-Auth (AES-CBC *) case */
+		sop->cipher.data.offset = sa->ctp.cipher.offset + hlen;
+		sop->cipher.data.length = sa->ctp.cipher.length + plen;
+		sop->auth.data.offset = sa->ctp.auth.offset + hlen;
+		sop->auth.data.length = sa->ctp.auth.length + plen;
+		sop->auth.digest.data = icv->va;
+		sop->auth.digest.phys_addr = icv->pa;
+		break;
+	case ALGO_TYPE_AES_CTR:
+		/* Cipher-Auth (AES-CTR *) case */
+		sop->cipher.data.offset = sa->ctp.cipher.offset + hlen;
+		sop->cipher.data.length = sa->ctp.cipher.length + plen;
+		sop->auth.data.offset = sa->ctp.auth.offset + hlen;
+		sop->auth.data.length = sa->ctp.auth.length + plen;
+		sop->auth.digest.data = icv->va;
+		sop->auth.digest.phys_addr = icv->pa;
+
+		ctr = rte_crypto_op_ctod_offset(cop, struct aesctr_cnt_blk *,
+			sa->iv_ofs);
+		aes_ctr_cnt_blk_fill(ctr, ivp[0], sa->salt);
+		break;
+	case ALGO_TYPE_NULL:
+		/* NULL case */
 		sop->cipher.data.offset = sa->ctp.cipher.offset + hlen;
 		sop->cipher.data.length = sa->ctp.cipher.length + plen;
 		sop->auth.data.offset = sa->ctp.auth.offset + hlen;
 		sop->auth.data.length = sa->ctp.auth.length + plen;
 		sop->auth.digest.data = icv->va;
 		sop->auth.digest.phys_addr = icv->pa;
+		break;
+	default:
+		break;
 	}
 }
 
@@ -561,6 +621,7 @@ outb_pkt_xprepare(const struct rte_ipsec_sa *sa, rte_be64_t sqc,
 {
 	uint32_t *psqh;
 	struct aead_gcm_aad *aad;
+	uint8_t algo_type = sa->algo_type;
 
 	/* insert SQN.hi between ESP trailer and ICV */
 	if (sa->sqh_len != 0) {
@@ -572,7 +633,7 @@ outb_pkt_xprepare(const struct rte_ipsec_sa *sa, rte_be64_t sqc,
 	 * fill IV and AAD fields, if any (aad fields are placed after icv),
 	 * right now we support only one AEAD algorithm: AES-GCM .
 	 */
-	if (sa->aad_len != 0) {
+	if (algo_type == ALGO_TYPE_AES_GCM) {
 		aad = (struct aead_gcm_aad *)(icv->va + sa->icv_len);
 		aead_gcm_aad_fill(aad, sa->spi, sqc, IS_ESN(sa));
 	}
@@ -783,8 +844,10 @@ esp_inb_tun_cop_prepare(struct rte_crypto_op *cop,
 {
 	struct rte_crypto_sym_op *sop;
 	struct aead_gcm_iv *gcm;
+	struct aesctr_cnt_blk *ctr;
 	uint64_t *ivc, *ivp;
 	uint32_t clen;
+	uint8_t algo_type = sa->algo_type;
 
 	clen = plen - sa->ctp.cipher.length;
 	if ((int32_t)clen < 0 || (clen & (sa->pad_align - 1)) != 0)
@@ -793,8 +856,8 @@ esp_inb_tun_cop_prepare(struct rte_crypto_op *cop,
 	/* fill sym op fields */
 	sop = cop->sym;
 
-	/* AEAD (AES_GCM) case */
-	if (sa->aad_len != 0) {
+	switch (algo_type) {
+	case ALGO_TYPE_AES_GCM:
 		sop->aead.data.offset = pofs + sa->ctp.cipher.offset;
 		sop->aead.data.length = clen;
 		sop->aead.digest.data = icv->va;
@@ -808,8 +871,8 @@ esp_inb_tun_cop_prepare(struct rte_crypto_op *cop,
 		ivp = rte_pktmbuf_mtod_offset(mb, uint64_t *,
 			pofs + sizeof(struct esp_hdr));
 		aead_gcm_iv_fill(gcm, ivp[0], sa->salt);
-	/* CRYPT+AUTH case */
-	} else {
+		break;
+	case ALGO_TYPE_AES_CBC:
 		sop->cipher.data.offset = pofs + sa->ctp.cipher.offset;
 		sop->cipher.data.length = clen;
 		sop->auth.data.offset = pofs + sa->ctp.auth.offset;
@@ -822,7 +885,35 @@ esp_inb_tun_cop_prepare(struct rte_crypto_op *cop,
 		ivp = rte_pktmbuf_mtod_offset(mb, uint64_t *,
 			pofs + sizeof(struct esp_hdr));
 		copy_iv(ivc, ivp, sa->iv_len);
+		break;
+	case ALGO_TYPE_AES_CTR:
+		sop->cipher.data.offset = pofs + sa->ctp.cipher.offset;
+		sop->cipher.data.length = clen;
+		sop->auth.data.offset = pofs + sa->ctp.auth.offset;
+		sop->auth.data.length = plen - sa->ctp.auth.length;
+		sop->auth.digest.data = icv->va;
+		sop->auth.digest.phys_addr = icv->pa;
+
+		/* copy iv from the input packet to the cop */
+		ctr = rte_crypto_op_ctod_offset(cop, struct aesctr_cnt_blk *,
+			sa->iv_ofs);
+		ivp = rte_pktmbuf_mtod_offset(mb, uint64_t *,
+			pofs + sizeof(struct esp_hdr));
+		aes_ctr_cnt_blk_fill(ctr, ivp[0], sa->salt);
+		break;
+	case ALGO_TYPE_NULL:
+		sop->cipher.data.offset = pofs + sa->ctp.cipher.offset;
+		sop->cipher.data.length = clen;
+		sop->auth.data.offset = pofs + sa->ctp.auth.offset;
+		sop->auth.data.length = plen - sa->ctp.auth.length;
+		sop->auth.digest.data = icv->va;
+		sop->auth.digest.phys_addr = icv->pa;
+		break;
+
+	default:
+		return -EINVAL;
 	}
+
 	return 0;
 }
 
diff --git a/lib/librte_ipsec/sa.h b/lib/librte_ipsec/sa.h
index 392e8fd7b..12c061ee6 100644
--- a/lib/librte_ipsec/sa.h
+++ b/lib/librte_ipsec/sa.h
@@ -15,10 +15,17 @@
 enum {
 	IPSEC_PAD_DEFAULT = 4,
 	IPSEC_PAD_AES_CBC = IPSEC_MAX_IV_SIZE,
+	IPSEC_PAD_AES_CTR = IPSEC_PAD_DEFAULT,
 	IPSEC_PAD_AES_GCM = IPSEC_PAD_DEFAULT,
 	IPSEC_PAD_NULL = IPSEC_PAD_DEFAULT,
 };
 
+/* iv sizes for different algorithms */
+enum {
+	IPSEC_IV_SIZE_DEFAULT = IPSEC_MAX_IV_SIZE,
+	IPSEC_AES_CTR_IV_SIZE = sizeof(uint64_t),
+};
+
 /* these definitions probably has to be in rte_crypto_sym.h */
 union sym_op_ofslen {
 	uint64_t raw;
@@ -47,7 +54,17 @@ struct replay_sqn {
 	__extension__ uint64_t window[0];
 };
 
+/*IPSEC SA supported algorithms */
+enum sa_algo_type	{
+	ALGO_TYPE_NULL = 0,
+	ALGO_TYPE_AES_CBC,
+	ALGO_TYPE_AES_CTR,
+	ALGO_TYPE_AES_GCM,
+	ALGO_TYPE_MAX
+};
+
 struct rte_ipsec_sa {
+
 	uint64_t type;     /* type of given SA */
 	uint64_t udata;    /* user defined */
 	uint32_t size;     /* size of given sa object */
@@ -65,6 +82,7 @@ struct rte_ipsec_sa {
 		union sym_op_ofslen auth;
 	} ctp;
 	uint32_t salt;
+	uint8_t algo_type;
 	uint8_t proto;    /* next proto */
 	uint8_t aad_len;
 	uint8_t hdr_len;
-- 
2.14.5

  reply	other threads:[~2019-02-25 12:08 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-18 16:32 [PATCH 0/4] ipsec: add AES-CTR and 3DES-CBC support Fan Zhang
2019-02-18 16:32 ` [PATCH 1/4] ipsec: add AES-CTR algorithm support Fan Zhang
2019-02-18 16:32 ` [PATCH 2/4] ipsec-secgw: add test scripts for aes ctr Fan Zhang
2019-02-18 16:32 ` [PATCH 3/4] ipsec: add 3DES-CBC algorithm support Fan Zhang
2019-02-18 16:32 ` [PATCH 4/4] ipsec-secgw: add 3des test files Fan Zhang
2019-02-19 15:32 ` [PATCH v2 0/4] ipsec: add AES-CTR and 3DES-CBC support Fan Zhang
2019-02-19 15:32   ` [PATCH v2 1/4] ipsec: add AES-CTR algorithm support Fan Zhang
2019-02-22 12:43     ` Ananyev, Konstantin
2019-03-19 14:32     ` Akhil Goyal
2019-02-19 15:32   ` [PATCH v2 2/4] ipsec-secgw: add test scripts for aes ctr Fan Zhang
2019-02-22 12:39     ` Ananyev, Konstantin
2019-02-19 15:32   ` [PATCH v2 3/4] ipsec: add 3DES-CBC algorithm support Fan Zhang
2019-02-22 12:38     ` Ananyev, Konstantin
2019-03-19 14:46     ` Akhil Goyal
2019-02-19 15:32   ` [PATCH v2 4/4] ipsec-secgw: add 3des test files Fan Zhang
2019-02-22 12:40     ` Ananyev, Konstantin
2019-02-25 12:07   ` [PATCH v3 0/4] ipsec: add AES-CTR and 3DES-CBC support Fan Zhang
2019-02-25 12:07     ` Fan Zhang [this message]
2019-02-25 12:07     ` [PATCH v3 2/4] ipsec-secgw: add test scripts for aes ctr Fan Zhang
2019-02-25 12:07     ` [PATCH v3 3/4] ipsec: add 3DES-CBC algorithm support Fan Zhang
2019-02-25 12:07     ` [PATCH v3 4/4] ipsec-secgw: add 3des test files Fan Zhang
2019-03-04 16:38     ` [PATCH v3 0/4] ipsec: add AES-CTR and 3DES-CBC support Ananyev, Konstantin
2019-03-20 13:51     ` [PATCH v4 0/4] ipsec: support AES-CTR and 3DES-CBC Fan Zhang
2019-03-20 13:51       ` [PATCH v4 1/4] ipsec: support AES-CTR Fan Zhang
2019-03-20 13:51       ` [PATCH v4 2/4] ipsec-secgw: add test scripts for aes ctr Fan Zhang
2019-03-20 13:51       ` [PATCH v4 3/4] ipsec: support 3DES-CBC Fan Zhang
2019-03-20 13:51       ` [PATCH v4 4/4] ipsec-secgw: add 3des test files Fan Zhang
2019-03-20 15:38       ` [PATCH v5 0/5] ipsec: support AES-CTR and 3DES-CBC Fan Zhang
2019-03-20 15:38         ` [PATCH v5 1/5] ipsec: support AES-CTR Fan Zhang
2019-03-22 11:53           ` Akhil Goyal
2019-03-22 12:46             ` Ananyev, Konstantin
2019-03-22 13:01               ` Akhil Goyal
2019-03-20 15:38         ` [PATCH v5 2/5] ipsec-secgw: add test scripts for aes ctr Fan Zhang
2019-03-20 15:38         ` [PATCH v5 3/5] ipsec: support 3DES-CBC Fan Zhang
2019-03-20 15:38         ` [PATCH v5 4/5] ipsec-secgw: add 3des test files Fan Zhang
2019-03-20 15:38         ` [PATCH v5 5/5] doc: update release note Fan Zhang
2019-03-22 14:59         ` [PATCH v5 0/5] ipsec: support AES-CTR and 3DES-CBC Akhil Goyal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190225120745.61836-2-roy.fan.zhang@intel.com \
    --to=roy.fan.zhang@intel.com \
    --cc=akhil.goyal@nxp.com \
    --cc=dev@dpdk.org \
    --cc=konstantin.ananyev@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.