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, arkadiuszx.kusztal@intel.com
Subject: [PATCH v2 1/3] crypto/aesni_mb: add aes-gcm algorithm support
Date: Tue,  9 Oct 2018 21:10:54 +0100	[thread overview]
Message-ID: <20181009201056.37344-2-roy.fan.zhang@intel.com> (raw)
In-Reply-To: <20181009201056.37344-1-roy.fan.zhang@intel.com>

This patch adds AES-GCM algorithm support to AESNI-MB PMD.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
---
 drivers/crypto/aesni_mb/aesni_mb_ops.h             |  28 +++-
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c         | 160 +++++++++++++++------
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c     |  30 ++++
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h |   3 +
 4 files changed, 174 insertions(+), 47 deletions(-)

diff --git a/drivers/crypto/aesni_mb/aesni_mb_ops.h b/drivers/crypto/aesni_mb/aesni_mb_ops.h
index d224b7249..575d6a5b8 100644
--- a/drivers/crypto/aesni_mb/aesni_mb_ops.h
+++ b/drivers/crypto/aesni_mb/aesni_mb_ops.h
@@ -48,6 +48,8 @@ typedef void (*aes_cmac_sub_key_gen_t)
 		(const void *exp_key, void *k2, void *k3);
 typedef void (*aes_cmac_keyexp_t)
 		(const void *key, void *keyexp);
+typedef void (*aes_gcm_keyexp_t)
+		(const void *key, struct gcm_key_data *keyexp);
 
 /** Multi-buffer library function pointer table */
 struct aesni_mb_op_fns {
@@ -95,6 +97,12 @@ struct aesni_mb_op_fns {
 			/**< AES CMAC subkey expansions */
 			aes_cmac_keyexp_t aes_cmac_expkey;
 			/**< AES CMAC key expansions */
+			aes_gcm_keyexp_t aes_gcm_128;
+			/**< AES GCM 128 key expansions */
+			aes_gcm_keyexp_t aes_gcm_192;
+			/**< AES GCM 192 key expansions */
+			aes_gcm_keyexp_t aes_gcm_256;
+			/**< AES GCM 256 key expansions */
 		} keyexp;
 		/**< Key expansion functions */
 #if IMB_VERSION_NUM >= IMB_VERSION(0, 50, 0)
@@ -155,7 +163,10 @@ static const struct aesni_mb_op_fns job_ops[] = {
 					aes_keyexp_256_sse,
 					aes_xcbc_expand_key_sse,
 					aes_cmac_subkey_gen_sse,
-					aes_keyexp_128_enc_sse
+					aes_keyexp_128_enc_sse,
+					aes_gcm_pre_128_sse,
+					aes_gcm_pre_192_sse,
+					aes_gcm_pre_256_sse
 				},
 #if IMB_VERSION_NUM >= IMB_VERSION(0, 50, 0)
 				.multi_block = {
@@ -191,7 +202,10 @@ static const struct aesni_mb_op_fns job_ops[] = {
 					aes_keyexp_256_avx,
 					aes_xcbc_expand_key_avx,
 					aes_cmac_subkey_gen_avx,
-					aes_keyexp_128_enc_avx
+					aes_keyexp_128_enc_avx,
+					aes_gcm_pre_128_avx_gen2,
+					aes_gcm_pre_192_avx_gen2,
+					aes_gcm_pre_256_avx_gen2
 				},
 #if IMB_VERSION_NUM >= IMB_VERSION(0, 50, 0)
 				.multi_block = {
@@ -227,7 +241,10 @@ static const struct aesni_mb_op_fns job_ops[] = {
 					aes_keyexp_256_avx2,
 					aes_xcbc_expand_key_avx2,
 					aes_cmac_subkey_gen_avx2,
-					aes_keyexp_128_enc_avx2
+					aes_keyexp_128_enc_avx2,
+					aes_gcm_pre_128_avx_gen4,
+					aes_gcm_pre_192_avx_gen4,
+					aes_gcm_pre_256_avx_gen4
 				},
 #if IMB_VERSION_NUM >= IMB_VERSION(0, 50, 0)
 				.multi_block = {
@@ -263,7 +280,10 @@ static const struct aesni_mb_op_fns job_ops[] = {
 					aes_keyexp_256_avx512,
 					aes_xcbc_expand_key_avx512,
 					aes_cmac_subkey_gen_avx512,
-					aes_keyexp_128_enc_avx512
+					aes_keyexp_128_enc_avx512,
+					aes_gcm_pre_128_avx_gen4,
+					aes_gcm_pre_192_avx_gen4,
+					aes_gcm_pre_256_avx_gen4
 				},
 #if IMB_VERSION_NUM >= IMB_VERSION(0, 50, 0)
 				.multi_block = {
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
index 05f08a6e6..83250e32c 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
@@ -86,7 +86,8 @@ aesni_mb_get_chain_order(const struct rte_crypto_sym_xform *xform)
 	}
 
 	if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
-		if (xform->aead.algo == RTE_CRYPTO_AEAD_AES_CCM) {
+		if (xform->aead.algo == RTE_CRYPTO_AEAD_AES_CCM ||
+				xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
 			if (xform->aead.op == RTE_CRYPTO_AEAD_OP_ENCRYPT)
 				return AESNI_MB_OP_AEAD_CIPHER_HASH;
 			else
@@ -444,7 +445,10 @@ aesni_mb_set_session_aead_parameters(const struct aesni_mb_op_fns *mb_ops,
 		struct aesni_mb_session *sess,
 		const struct rte_crypto_sym_xform *xform)
 {
-	aes_keyexp_t aes_keyexp_fn;
+	union {
+		aes_keyexp_t aes_keyexp_fn;
+		aes_gcm_keyexp_t aes_gcm_keyexp_fn;
+	} keyexp;
 
 	switch (xform->aead.op) {
 	case RTE_CRYPTO_AEAD_OP_ENCRYPT:
@@ -464,7 +468,53 @@ aesni_mb_set_session_aead_parameters(const struct aesni_mb_op_fns *mb_ops,
 	case RTE_CRYPTO_AEAD_AES_CCM:
 		sess->cipher.mode = CCM;
 		sess->auth.algo = AES_CCM;
+
+		/* Check key length and choose key expansion function for AES */
+		switch (xform->aead.key.length) {
+		case AES_128_BYTES:
+			sess->cipher.key_length_in_bytes = AES_128_BYTES;
+			keyexp.aes_keyexp_fn = mb_ops->aux.keyexp.aes128;
+			break;
+		default:
+			AESNI_MB_LOG(ERR, "Invalid cipher key length");
+			return -EINVAL;
+		}
+
+		/* Expanded cipher keys */
+		(*keyexp.aes_keyexp_fn)(xform->aead.key.data,
+				sess->cipher.expanded_aes_keys.encode,
+				sess->cipher.expanded_aes_keys.decode);
 		break;
+
+	case RTE_CRYPTO_AEAD_AES_GCM:
+		sess->cipher.mode = GCM;
+		sess->auth.algo = AES_GMAC;
+
+		switch (xform->aead.key.length) {
+		case AES_128_BYTES:
+			sess->cipher.key_length_in_bytes = AES_128_BYTES;
+			keyexp.aes_gcm_keyexp_fn =
+					mb_ops->aux.keyexp.aes_gcm_128;
+			break;
+		case AES_192_BYTES:
+			sess->cipher.key_length_in_bytes = AES_192_BYTES;
+			keyexp.aes_gcm_keyexp_fn =
+					mb_ops->aux.keyexp.aes_gcm_192;
+			break;
+		case AES_256_BYTES:
+			sess->cipher.key_length_in_bytes = AES_256_BYTES;
+			keyexp.aes_gcm_keyexp_fn =
+					mb_ops->aux.keyexp.aes_gcm_256;
+			break;
+		default:
+			AESNI_MB_LOG(ERR, "Invalid cipher key length");
+			return -EINVAL;
+		}
+
+		(keyexp.aes_gcm_keyexp_fn)(xform->aead.key.data,
+				&sess->cipher.gcm_key);
+		break;
+
 	default:
 		AESNI_MB_LOG(ERR, "Unsupported aead mode parameter");
 		return -ENOTSUP;
@@ -484,23 +534,6 @@ aesni_mb_set_session_aead_parameters(const struct aesni_mb_op_fns *mb_ops,
 	}
 	sess->auth.gen_digest_len = sess->auth.req_digest_len;
 
-	/* Check key length and choose key expansion function for AES */
-
-	switch (xform->aead.key.length) {
-	case AES_128_BYTES:
-		sess->cipher.key_length_in_bytes = AES_128_BYTES;
-		aes_keyexp_fn = mb_ops->aux.keyexp.aes128;
-		break;
-	default:
-		AESNI_MB_LOG(ERR, "Invalid cipher key length");
-		return -EINVAL;
-	}
-
-	/* Expanded cipher keys */
-	(*aes_keyexp_fn)(xform->aead.key.data,
-			sess->cipher.expanded_aes_keys.encode,
-			sess->cipher.expanded_aes_keys.decode);
-
 	return 0;
 }
 
@@ -692,38 +725,62 @@ set_mb_job_params(JOB_AES_HMAC *job, struct aesni_mb_qp *qp,
 
 	job->aes_key_len_in_bytes = session->cipher.key_length_in_bytes;
 
-	if (job->cipher_mode == DES3) {
-		job->aes_enc_key_expanded =
-			session->cipher.exp_3des_keys.ks_ptr;
-		job->aes_dec_key_expanded =
-			session->cipher.exp_3des_keys.ks_ptr;
-	} else {
-		job->aes_enc_key_expanded =
-			session->cipher.expanded_aes_keys.encode;
-		job->aes_dec_key_expanded =
-			session->cipher.expanded_aes_keys.decode;
-	}
-
-
-
-
 	/* Set authentication parameters */
 	job->hash_alg = session->auth.algo;
-	if (job->hash_alg == AES_XCBC) {
+
+	switch (job->hash_alg) {
+	case AES_XCBC:
 		job->u.XCBC._k1_expanded = session->auth.xcbc.k1_expanded;
 		job->u.XCBC._k2 = session->auth.xcbc.k2;
 		job->u.XCBC._k3 = session->auth.xcbc.k3;
-	} else if (job->hash_alg == AES_CCM) {
+
+		job->aes_enc_key_expanded =
+				session->cipher.expanded_aes_keys.encode;
+		job->aes_dec_key_expanded =
+				session->cipher.expanded_aes_keys.decode;
+		break;
+
+	case AES_CCM:
 		job->u.CCM.aad = op->sym->aead.aad.data + 18;
 		job->u.CCM.aad_len_in_bytes = session->aead.aad_len;
-	} else if (job->hash_alg == AES_CMAC) {
+		job->aes_enc_key_expanded =
+				session->cipher.expanded_aes_keys.encode;
+		job->aes_dec_key_expanded =
+				session->cipher.expanded_aes_keys.decode;
+		break;
+
+	case AES_CMAC:
 		job->u.CMAC._key_expanded = session->auth.cmac.expkey;
 		job->u.CMAC._skey1 = session->auth.cmac.skey1;
 		job->u.CMAC._skey2 = session->auth.cmac.skey2;
+		job->aes_enc_key_expanded =
+				session->cipher.expanded_aes_keys.encode;
+		job->aes_dec_key_expanded =
+				session->cipher.expanded_aes_keys.decode;
+		break;
 
-	} else {
+	case AES_GMAC:
+		job->u.GCM.aad = op->sym->aead.aad.data;
+		job->u.GCM.aad_len_in_bytes = session->aead.aad_len;
+		job->aes_enc_key_expanded = &session->cipher.gcm_key;
+		job->aes_dec_key_expanded = &session->cipher.gcm_key;
+		break;
+
+	default:
 		job->u.HMAC._hashed_auth_key_xor_ipad = session->auth.pads.inner;
 		job->u.HMAC._hashed_auth_key_xor_opad = session->auth.pads.outer;
+
+		if (job->cipher_mode == DES3) {
+			job->aes_enc_key_expanded =
+				session->cipher.exp_3des_keys.ks_ptr;
+			job->aes_dec_key_expanded =
+				session->cipher.exp_3des_keys.ks_ptr;
+		} else {
+			job->aes_enc_key_expanded =
+				session->cipher.expanded_aes_keys.encode;
+			job->aes_dec_key_expanded =
+				session->cipher.expanded_aes_keys.decode;
+		}
 	}
 
 	/* Mutable crypto operation parameters */
@@ -744,7 +801,7 @@ set_mb_job_params(JOB_AES_HMAC *job, struct aesni_mb_qp *qp,
 				rte_pktmbuf_data_len(op->sym->m_src));
 	} else {
 		m_dst = m_src;
-		if (job->hash_alg == AES_CCM)
+		if (job->hash_alg == AES_CCM || job->hash_alg == AES_GMAC)
 			m_offset = op->sym->aead.data.offset;
 		else
 			m_offset = op->sym->cipher.data.offset;
@@ -756,7 +813,7 @@ set_mb_job_params(JOB_AES_HMAC *job, struct aesni_mb_qp *qp,
 		job->auth_tag_output = qp->temp_digests[*digest_idx];
 		*digest_idx = (*digest_idx + 1) % MAX_JOBS;
 	} else {
-		if (job->hash_alg == AES_CCM)
+		if (job->hash_alg == AES_CCM || job->hash_alg == AES_GMAC)
 			job->auth_tag_output = op->sym->aead.digest.data;
 		else
 			job->auth_tag_output = op->sym->auth.digest.data;
@@ -766,6 +823,10 @@ set_mb_job_params(JOB_AES_HMAC *job, struct aesni_mb_qp *qp,
 			*digest_idx = (*digest_idx + 1) % MAX_JOBS;
 		}
 	}
+	/*
+	 * Multi-buffer library current only support returning a truncated
+	 * digest length as specified in the relevant IPsec RFCs
+	 */
 
 	/* Set digest length */
 	job->auth_tag_output_len_in_bytes = session->auth.gen_digest_len;
@@ -777,7 +838,8 @@ set_mb_job_params(JOB_AES_HMAC *job, struct aesni_mb_qp *qp,
 	job->src = rte_pktmbuf_mtod(m_src, uint8_t *);
 	job->dst = rte_pktmbuf_mtod_offset(m_dst, uint8_t *, m_offset);
 
-	if (job->hash_alg == AES_CCM) {
+	switch (job->hash_alg) {
+	case AES_CCM:
 		job->cipher_start_src_offset_in_bytes =
 				op->sym->aead.data.offset;
 		job->msg_len_to_cipher_in_bytes = op->sym->aead.data.length;
@@ -786,7 +848,19 @@ set_mb_job_params(JOB_AES_HMAC *job, struct aesni_mb_qp *qp,
 
 		job->iv = rte_crypto_op_ctod_offset(op, uint8_t *,
 			session->iv.offset + 1);
-	} else {
+		break;
+
+	case AES_GMAC:
+		job->cipher_start_src_offset_in_bytes =
+				op->sym->aead.data.offset;
+		job->hash_start_src_offset_in_bytes = op->sym->aead.data.offset;
+		job->msg_len_to_cipher_in_bytes = op->sym->aead.data.length;
+		job->msg_len_to_hash_in_bytes = job->msg_len_to_cipher_in_bytes;
+		job->iv = rte_crypto_op_ctod_offset(op, uint8_t *,
+				session->iv.offset);
+		break;
+
+	default:
 		job->cipher_start_src_offset_in_bytes =
 				op->sym->cipher.data.offset;
 		job->msg_len_to_cipher_in_bytes = op->sym->cipher.data.length;
@@ -809,7 +883,7 @@ verify_digest(JOB_AES_HMAC *job, struct rte_crypto_op *op,
 		struct aesni_mb_session *sess)
 {
 	/* Verify digest if required */
-	if (job->hash_alg == AES_CCM) {
+	if (job->hash_alg == AES_CCM || job->hash_alg == AES_GMAC) {
 		if (memcmp(job->auth_tag_output, op->sym->aead.digest.data,
 				sess->auth.req_digest_len) != 0)
 			op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
index 4f0139b20..43f6c26ed 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
@@ -386,6 +386,36 @@ static const struct rte_cryptodev_capabilities aesni_mb_pmd_capabilities[] = {
 			}, }
 		}, }
 	},
+	{	/* AES GCM */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AEAD,
+			{.aead = {
+				.algo = RTE_CRYPTO_AEAD_AES_GCM,
+				.block_size = 16,
+				.key_size = {
+					.min = 16,
+					.max = 32,
+					.increment = 8
+				},
+				.digest_size = {
+					.min = 8,
+					.max = 16,
+					.increment = 4
+				},
+				.aad_size = {
+					.min = 0,
+					.max = 65535,
+					.increment = 1
+				},
+				.iv_size = {
+					.min = 12,
+					.max = 12,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
 
diff --git a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
index 8c027a87e..d8021cdaa 100644
--- a/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
+++ b/drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
@@ -82,6 +82,7 @@ static const unsigned auth_digest_byte_lengths[] = {
 		[SHA_512]	= 64,
 		[AES_XCBC]	= 16,
 		[AES_CMAC]	= 16,
+		[AES_GMAC]	= 12,
 		[NULL_HASH]		= 0
 };
 
@@ -172,6 +173,8 @@ struct aesni_mb_session {
 				const void *ks_ptr[3];
 				uint64_t key[3][16];
 			} exp_3des_keys;
+
+			struct gcm_key_data gcm_key;
 		};
 		/**< Expanded AES keys - Allocating space to
 		 * contain the maximum expanded key size which
-- 
2.13.6

  reply	other threads:[~2018-10-09 20:26 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-07 10:44 [PATCH 0/3] crypto/aesni_mb: add aes-gcm support Fan Zhang
2018-09-07 10:44 ` [PATCH 1/3] crypto/aesni_mb: add aes-gcm algorithm support Fan Zhang
2018-09-07 10:44 ` [PATCH 2/3] test/test_cryptodev: add AES-GCM tests to AESNI-MB Fan Zhang
2018-09-07 10:44 ` [PATCH 3/3] doc: update cryptodev and release note Fan Zhang
2018-10-09 20:10 ` [PATCH v2 0/3] crypto/aesni_mb: add aes-gcm support Fan Zhang
2018-10-09 20:10   ` Fan Zhang [this message]
2018-10-09 20:10   ` [PATCH v2 2/3] test/test_cryptodev: add AES-GCM tests to AESNI-MB Fan Zhang
2018-10-09 20:10   ` [PATCH v2 3/3] doc: update cryptodev and release note Fan Zhang
2018-10-10  9:49   ` [PATCH v2 0/3] crypto/aesni_mb: add aes-gcm support Kusztal, ArkadiuszX
2018-10-10 10:42   ` Akhil Goyal
2018-10-10 11:04   ` [PATCH v3 " Fan Zhang
2018-10-10 11:04     ` [PATCH v3 1/3] crypto/aesni_mb: add aes-gcm algorithm support Fan Zhang
2018-10-10 11:04     ` [PATCH v3 2/3] test/test_cryptodev: add AES-GCM tests to AESNI-MB Fan Zhang
2018-10-10 11:04     ` [PATCH v3 3/3] doc: update cryptodev and release note Fan Zhang
2018-10-10 11:39     ` [PATCH v3 0/3] crypto/aesni_mb: add aes-gcm support 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=20181009201056.37344-2-roy.fan.zhang@intel.com \
    --to=roy.fan.zhang@intel.com \
    --cc=akhil.goyal@nxp.com \
    --cc=arkadiuszx.kusztal@intel.com \
    --cc=dev@dpdk.org \
    /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.