[v6,1/2] crypto/ipsec_mb: add digest encrypted feature

Message ID 20230907102614.2269913-2-brian.dooley@intel.com (mailing list archive)
State Superseded, archived
Delegated to: akhil goyal
Headers
Series [v6,1/2] crypto/ipsec_mb: add digest encrypted feature |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Brian Dooley Sept. 7, 2023, 10:26 a.m. UTC
  AESNI_MB PMD does not support Digest Encrypted. This patch adds a check and
support for this feature.

Signed-off-by: Brian Dooley <brian.dooley@intel.com>
---
v2:
Fixed CHECKPATCH warning
v3:
Add Digest encrypted support to docs
v4:
Add comments and small refactor
v5:
Fix checkpatch warnings
v6:
Add skipping tests for synchronous crypto
---
 app/test/test_cryptodev.c                   |   6 ++
 doc/guides/cryptodevs/features/aesni_mb.ini |   1 +
 drivers/crypto/ipsec_mb/pmd_aesni_mb.c      | 109 +++++++++++++++++++-
 3 files changed, 111 insertions(+), 5 deletions(-)
  

Comments

Power, Ciara Sept. 7, 2023, 3:25 p.m. UTC | #1
Hi Brian,

> -----Original Message-----
> From: Brian Dooley <brian.dooley@intel.com>
> Sent: Thursday, September 7, 2023 11:26 AM
> To: Akhil Goyal <gakhil@marvell.com>; Fan Zhang <fanzhang.oss@gmail.com>;
> Ji, Kai <kai.ji@intel.com>; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>
> Cc: dev@dpdk.org; Dooley, Brian <brian.dooley@intel.com>
> Subject: [PATCH v6 1/2] crypto/ipsec_mb: add digest encrypted feature
> 
> AESNI_MB PMD does not support Digest Encrypted. This patch adds a check
> and support for this feature.
> 
> Signed-off-by: Brian Dooley <brian.dooley@intel.com>
> ---
> v2:
> Fixed CHECKPATCH warning
> v3:
> Add Digest encrypted support to docs
> v4:
> Add comments and small refactor
> v5:
> Fix checkpatch warnings
> v6:
> Add skipping tests for synchronous crypto
> ---
>  app/test/test_cryptodev.c                   |   6 ++
>  doc/guides/cryptodevs/features/aesni_mb.ini |   1 +
>  drivers/crypto/ipsec_mb/pmd_aesni_mb.c      | 109
> +++++++++++++++++++-
>  3 files changed, 111 insertions(+), 5 deletions(-)
> 
> diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c index
> 956268bfcd..70f6b7ece1 100644
> --- a/app/test/test_cryptodev.c
> +++ b/app/test/test_cryptodev.c
> @@ -6394,6 +6394,9 @@ test_zuc_auth_cipher(const struct
> wireless_test_data *tdata,
>  			tdata->digest.len) < 0)
>  		return TEST_SKIPPED;
> 
> +	if (gbl_action_type == RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO)
> +		return TEST_SKIPPED;
> +
>  	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
> 
>  	uint64_t feat_flags = dev_info.feature_flags; @@ -7829,6 +7832,9
> @@ test_mixed_auth_cipher(const struct mixed_cipher_auth_test_data
> *tdata,
>  	if (global_api_test_type == CRYPTODEV_RAW_API_TEST)
>  		return TEST_SKIPPED;
> 
> +	if (gbl_action_type == RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO)
> +		return TEST_SKIPPED;
> +
>  	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
> 
<snip>

Small thing, I think the above fixes should be in their own fix patch.

Code changes look good to me. Can keep my ack on v7 with the fixes split out.

Acked-by: Ciara Power <ciara.power@intel.com>
  

Patch

diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c
index 956268bfcd..70f6b7ece1 100644
--- a/app/test/test_cryptodev.c
+++ b/app/test/test_cryptodev.c
@@ -6394,6 +6394,9 @@  test_zuc_auth_cipher(const struct wireless_test_data *tdata,
 			tdata->digest.len) < 0)
 		return TEST_SKIPPED;
 
+	if (gbl_action_type == RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO)
+		return TEST_SKIPPED;
+
 	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
 
 	uint64_t feat_flags = dev_info.feature_flags;
@@ -7829,6 +7832,9 @@  test_mixed_auth_cipher(const struct mixed_cipher_auth_test_data *tdata,
 	if (global_api_test_type == CRYPTODEV_RAW_API_TEST)
 		return TEST_SKIPPED;
 
+	if (gbl_action_type == RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO)
+		return TEST_SKIPPED;
+
 	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
 
 	uint64_t feat_flags = dev_info.feature_flags;
diff --git a/doc/guides/cryptodevs/features/aesni_mb.ini b/doc/guides/cryptodevs/features/aesni_mb.ini
index e4e965c35a..8df5fa2c85 100644
--- a/doc/guides/cryptodevs/features/aesni_mb.ini
+++ b/doc/guides/cryptodevs/features/aesni_mb.ini
@@ -20,6 +20,7 @@  OOP LB  In LB  Out     = Y
 CPU crypto             = Y
 Symmetric sessionless  = Y
 Non-Byte aligned data  = Y
+Digest encrypted       = Y
 
 ;
 ; Supported crypto algorithms of the 'aesni_mb' crypto driver.
diff --git a/drivers/crypto/ipsec_mb/pmd_aesni_mb.c b/drivers/crypto/ipsec_mb/pmd_aesni_mb.c
index 9e298023d7..7f61065939 100644
--- a/drivers/crypto/ipsec_mb/pmd_aesni_mb.c
+++ b/drivers/crypto/ipsec_mb/pmd_aesni_mb.c
@@ -1438,6 +1438,54 @@  set_gcm_job(IMB_MGR *mb_mgr, IMB_JOB *job, const uint8_t sgl,
 	return 0;
 }
 
+/** Check if conditions are met for digest-appended operations */
+static uint8_t *
+aesni_mb_digest_appended_in_src(struct rte_crypto_op *op, IMB_JOB *job,
+		uint32_t oop)
+{
+	unsigned int auth_size, cipher_size;
+	uint8_t *end_cipher;
+	uint8_t *start_cipher;
+
+	if (job->cipher_mode == IMB_CIPHER_NULL)
+		return NULL;
+
+	if (job->cipher_mode == IMB_CIPHER_ZUC_EEA3 ||
+		job->cipher_mode == IMB_CIPHER_SNOW3G_UEA2_BITLEN ||
+		job->cipher_mode == IMB_CIPHER_KASUMI_UEA1_BITLEN) {
+		cipher_size = (op->sym->cipher.data.offset >> 3) +
+			(op->sym->cipher.data.length >> 3);
+	} else {
+		cipher_size = (op->sym->cipher.data.offset) +
+			(op->sym->cipher.data.length);
+	}
+	if (job->hash_alg == IMB_AUTH_ZUC_EIA3_BITLEN ||
+		job->hash_alg == IMB_AUTH_SNOW3G_UIA2_BITLEN ||
+		job->hash_alg == IMB_AUTH_KASUMI_UIA1 ||
+		job->hash_alg == IMB_AUTH_ZUC256_EIA3_BITLEN) {
+		auth_size = (op->sym->auth.data.offset >> 3) +
+			(op->sym->auth.data.length >> 3);
+	} else {
+		auth_size = (op->sym->auth.data.offset) +
+			(op->sym->auth.data.length);
+	}
+
+	if (!oop) {
+		end_cipher = rte_pktmbuf_mtod_offset(op->sym->m_src, uint8_t *, cipher_size);
+		start_cipher = rte_pktmbuf_mtod(op->sym->m_src, uint8_t *);
+	} else {
+		end_cipher = rte_pktmbuf_mtod_offset(op->sym->m_dst, uint8_t *, cipher_size);
+		start_cipher = rte_pktmbuf_mtod(op->sym->m_dst, uint8_t *);
+	}
+
+	if (start_cipher < op->sym->auth.digest.data &&
+		op->sym->auth.digest.data < end_cipher) {
+		return rte_pktmbuf_mtod_offset(op->sym->m_src, uint8_t *, auth_size);
+	} else {
+		return NULL;
+	}
+}
+
 /**
  * Process a crypto operation and complete a IMB_JOB job structure for
  * submission to the multi buffer library for processing.
@@ -1580,9 +1628,12 @@  set_mb_job_params(IMB_JOB *job, struct ipsec_mb_qp *qp,
 	} else {
 		if (aead)
 			job->auth_tag_output = op->sym->aead.digest.data;
-		else
-			job->auth_tag_output = op->sym->auth.digest.data;
-
+		else {
+			job->auth_tag_output = aesni_mb_digest_appended_in_src(op, job, oop);
+			if (job->auth_tag_output == NULL) {
+				job->auth_tag_output = op->sym->auth.digest.data;
+			}
+		}
 		if (session->auth.req_digest_len !=
 				job->auth_tag_output_len_in_bytes) {
 			job->auth_tag_output =
@@ -1917,6 +1968,7 @@  post_process_mb_job(struct ipsec_mb_qp *qp, IMB_JOB *job)
 	struct aesni_mb_session *sess = NULL;
 	uint8_t *linear_buf = NULL;
 	int sgl = 0;
+	uint8_t oop = 0;
 	uint8_t is_docsis_sec = 0;
 
 	if (op->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION) {
@@ -1962,8 +2014,54 @@  post_process_mb_job(struct ipsec_mb_qp *qp, IMB_JOB *job)
 						op->sym->auth.digest.data,
 						sess->auth.req_digest_len,
 						&op->status);
-			} else
+			} else {
+				if (!op->sym->m_dst || op->sym->m_dst == op->sym->m_src) {
+					/* in-place operation */
+					oop = 0;
+				} else { /* out-of-place operation */
+					oop = 1;
+				}
+
+				/* Enable digest check */
+				if (op->sym->m_src->nb_segs == 1 && op->sym->m_dst != NULL
+				&& !is_aead_algo(job->hash_alg,	sess->template_job.cipher_mode) &&
+				aesni_mb_digest_appended_in_src(op, job, oop) != NULL) {
+					unsigned int auth_size, cipher_size;
+					int unencrypted_bytes = 0;
+					if (job->cipher_mode == IMB_CIPHER_SNOW3G_UEA2_BITLEN ||
+						job->cipher_mode == IMB_CIPHER_KASUMI_UEA1_BITLEN ||
+						job->cipher_mode == IMB_CIPHER_ZUC_EEA3) {
+						cipher_size = (op->sym->cipher.data.offset >> 3) +
+							(op->sym->cipher.data.length >> 3);
+					} else {
+						cipher_size = (op->sym->cipher.data.offset) +
+							(op->sym->cipher.data.length);
+					}
+					if (job->hash_alg == IMB_AUTH_ZUC_EIA3_BITLEN ||
+						job->hash_alg == IMB_AUTH_SNOW3G_UIA2_BITLEN ||
+						job->hash_alg == IMB_AUTH_KASUMI_UIA1 ||
+						job->hash_alg == IMB_AUTH_ZUC256_EIA3_BITLEN) {
+						auth_size = (op->sym->auth.data.offset >> 3) +
+							(op->sym->auth.data.length >> 3);
+					} else {
+						auth_size = (op->sym->auth.data.offset) +
+						(op->sym->auth.data.length);
+					}
+					/* Check for unencrypted bytes in partial digest cases */
+					if (job->cipher_mode != IMB_CIPHER_NULL) {
+						unencrypted_bytes = auth_size +
+						job->auth_tag_output_len_in_bytes - cipher_size;
+					}
+					if (unencrypted_bytes > 0)
+						rte_memcpy(
+						rte_pktmbuf_mtod_offset(op->sym->m_dst, uint8_t *,
+						cipher_size),
+						rte_pktmbuf_mtod_offset(op->sym->m_src, uint8_t *,
+						cipher_size),
+						unencrypted_bytes);
+				}
 				generate_digest(job, op, sess);
+			}
 			break;
 		default:
 			op->status = RTE_CRYPTO_OP_STATUS_ERROR;
@@ -2555,7 +2653,8 @@  RTE_INIT(ipsec_mb_register_aesni_mb)
 			RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT |
 			RTE_CRYPTODEV_FF_OOP_LB_IN_SGL_OUT |
 			RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT |
-			RTE_CRYPTODEV_FF_SECURITY;
+			RTE_CRYPTODEV_FF_SECURITY |
+			RTE_CRYPTODEV_FF_DIGEST_ENCRYPTED;
 
 	aesni_mb_data->internals_priv_size = 0;
 	aesni_mb_data->ops = &aesni_mb_pmd_ops;