DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH] crypto/openssl: support SG for inplace buffers
@ 2019-09-02 12:42 Akhil Goyal
  2019-09-13  5:58 ` [dpdk-dev] [EXT] " Anoob Joseph
  2019-11-18 13:36 ` [dpdk-dev] [PATCH v2] " Akhil Goyal
  0 siblings, 2 replies; 10+ messages in thread
From: Akhil Goyal @ 2019-09-02 12:42 UTC (permalink / raw)
  To: dev
  Cc: hemant.agrawal, anoobj, jerinj, declan.doherty,
	konstantin.ananyev, Akhil Goyal

As per current support, scatter Gather is only supported
for out of place input and output buffers.
This patch add support for scatter gather for inplace buffers.

Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
---
 doc/guides/cryptodevs/features/openssl.ini |  1 +
 drivers/crypto/openssl/rte_openssl_pmd.c   | 82 +++++++++++++++++-----
 2 files changed, 64 insertions(+), 19 deletions(-)

diff --git a/doc/guides/cryptodevs/features/openssl.ini b/doc/guides/cryptodevs/features/openssl.ini
index 6ddca39e7..30ffb111d 100644
--- a/doc/guides/cryptodevs/features/openssl.ini
+++ b/doc/guides/cryptodevs/features/openssl.ini
@@ -6,6 +6,7 @@
 [Features]
 Symmetric crypto       = Y
 Sym operation chaining = Y
+In Place SGL           = Y
 OOP SGL In LB  Out     = Y
 OOP LB  In LB  Out     = Y
 Asymmetric crypto      = Y
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index 2f5552840..304ebc6ff 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -798,12 +798,12 @@ get_session(struct openssl_qp *qp, struct rte_crypto_op *op)
  */
 static inline int
 process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset,
-		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx)
+		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx, uint8_t inplace)
 {
 	struct rte_mbuf *m;
 	int dstlen;
 	int l, n = srclen;
-	uint8_t *src;
+	uint8_t *src, temp[128];
 
 	for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
 			m = m->next)
@@ -813,6 +813,8 @@ process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset,
 		return -1;
 
 	src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
+	if (inplace)
+		*dst = src;
 
 	l = rte_pktmbuf_data_len(m) - offset;
 	if (srclen <= l) {
@@ -829,8 +831,24 @@ process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset,
 	n -= l;
 
 	for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
+		uint8_t diff = l - dstlen, rem;
+
 		src = rte_pktmbuf_mtod(m, uint8_t *);
 		l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
+		if (diff && inplace) {
+			rem = l > (EVP_CIPHER_CTX_block_size(ctx) - diff) ?
+				(EVP_CIPHER_CTX_block_size(ctx) - diff) : l;
+			if (EVP_EncryptUpdate(ctx, temp,
+						&dstlen, src, rem) <= 0)
+				return -1;
+			n -= rem;
+			rte_memcpy(*dst, temp, diff);
+			rte_memcpy(src, temp + diff, rem);
+			src += rem;
+			l -= rem;
+		}
+		if (inplace)
+			*dst = src;
 		if (EVP_EncryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
 			return -1;
 		*dst += dstlen;
@@ -842,12 +860,12 @@ process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset,
 
 static inline int
 process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset,
-		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx)
+		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx, uint8_t inplace)
 {
 	struct rte_mbuf *m;
 	int dstlen;
 	int l, n = srclen;
-	uint8_t *src;
+	uint8_t *src, temp[128];
 
 	for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
 			m = m->next)
@@ -857,6 +875,8 @@ process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset,
 		return -1;
 
 	src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
+	if (inplace)
+		*dst = src;
 
 	l = rte_pktmbuf_data_len(m) - offset;
 	if (srclen <= l) {
@@ -873,8 +893,24 @@ process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset,
 	n -= l;
 
 	for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
+		uint8_t diff = l - dstlen, rem;
+
 		src = rte_pktmbuf_mtod(m, uint8_t *);
 		l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
+		if (diff && inplace) {
+			rem = l > (EVP_CIPHER_CTX_block_size(ctx) - diff) ?
+				(EVP_CIPHER_CTX_block_size(ctx) - diff) : l;
+			if (EVP_EncryptUpdate(ctx, temp,
+						&dstlen, src, rem) <= 0)
+				return -1;
+			n -= rem;
+			rte_memcpy(*dst, temp, diff);
+			rte_memcpy(src, temp + diff, rem);
+			src += rem;
+			l -= rem;
+		}
+		if (inplace)
+			*dst = src;
 		if (EVP_DecryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
 			return -1;
 		*dst += dstlen;
@@ -887,7 +923,8 @@ process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset,
 /** Process standard openssl cipher encryption */
 static int
 process_openssl_cipher_encrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
-		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx)
+		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx,
+		uint8_t inplace)
 {
 	int totlen;
 
@@ -897,7 +934,7 @@ process_openssl_cipher_encrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
 	EVP_CIPHER_CTX_set_padding(ctx, 0);
 
 	if (process_openssl_encryption_update(mbuf_src, offset, &dst,
-			srclen, ctx))
+			srclen, ctx, inplace))
 		goto process_cipher_encrypt_err;
 
 	if (EVP_EncryptFinal_ex(ctx, dst, &totlen) <= 0)
@@ -936,7 +973,8 @@ process_openssl_cipher_bpi_encrypt(uint8_t *src, uint8_t *dst,
 /** Process standard openssl cipher decryption */
 static int
 process_openssl_cipher_decrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
-		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx)
+		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx,
+		uint8_t inplace)
 {
 	int totlen;
 
@@ -946,7 +984,7 @@ process_openssl_cipher_decrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
 	EVP_CIPHER_CTX_set_padding(ctx, 0);
 
 	if (process_openssl_decryption_update(mbuf_src, offset, &dst,
-			srclen, ctx))
+			srclen, ctx, inplace))
 		goto process_cipher_decrypt_err;
 
 	if (EVP_DecryptFinal_ex(ctx, dst, &totlen) <= 0)
@@ -1033,7 +1071,7 @@ process_openssl_auth_encryption_gcm(struct rte_mbuf *mbuf_src, int offset,
 
 	if (srclen > 0)
 		if (process_openssl_encryption_update(mbuf_src, offset, &dst,
-				srclen, ctx))
+				srclen, ctx, 0))
 			goto process_auth_encryption_gcm_err;
 
 	/* Workaround open ssl bug in version less then 1.0.1f */
@@ -1078,7 +1116,7 @@ process_openssl_auth_encryption_ccm(struct rte_mbuf *mbuf_src, int offset,
 
 	if (srclen > 0)
 		if (process_openssl_encryption_update(mbuf_src, offset, &dst,
-				srclen, ctx))
+				srclen, ctx, 0))
 			goto process_auth_encryption_ccm_err;
 
 	if (EVP_EncryptFinal_ex(ctx, dst, &len) <= 0)
@@ -1115,7 +1153,7 @@ process_openssl_auth_decryption_gcm(struct rte_mbuf *mbuf_src, int offset,
 
 	if (srclen > 0)
 		if (process_openssl_decryption_update(mbuf_src, offset, &dst,
-				srclen, ctx))
+				srclen, ctx, 0))
 			goto process_auth_decryption_gcm_err;
 
 	/* Workaround open ssl bug in version less then 1.0.1f */
@@ -1161,7 +1199,7 @@ process_openssl_auth_decryption_ccm(struct rte_mbuf *mbuf_src, int offset,
 
 	if (srclen > 0)
 		if (process_openssl_decryption_update(mbuf_src, offset, &dst,
-				srclen, ctx))
+				srclen, ctx, 0))
 			return -EFAULT;
 
 	return 0;
@@ -1372,12 +1410,15 @@ process_openssl_cipher_op
 {
 	uint8_t *dst, *iv;
 	int srclen, status;
+	uint8_t inplace = (mbuf_src == mbuf_dst) ? 1 : 0;
 
 	/*
-	 * Segmented destination buffer is not supported for
-	 * encryption/decryption
+	 * Segmented OOP destination buffer is not supported for encryption/
+	 * decryption. In case of des3ctr, even inplace segmented buffers are
+	 * not supported.
 	 */
-	if (!rte_pktmbuf_is_contiguous(mbuf_dst)) {
+	if (!rte_pktmbuf_is_contiguous(mbuf_dst) &&
+			(!inplace || sess->cipher.mode != OPENSSL_CIPHER_LIB)) {
 		op->status = RTE_CRYPTO_OP_STATUS_ERROR;
 		return;
 	}
@@ -1393,11 +1434,13 @@ process_openssl_cipher_op
 		if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
 			status = process_openssl_cipher_encrypt(mbuf_src, dst,
 					op->sym->cipher.data.offset, iv,
-					srclen, sess->cipher.ctx);
+					srclen, sess->cipher.ctx,
+					inplace);
 		else
 			status = process_openssl_cipher_decrypt(mbuf_src, dst,
 					op->sym->cipher.data.offset, iv,
-					srclen, sess->cipher.ctx);
+					srclen, sess->cipher.ctx,
+					inplace);
 	else
 		status = process_openssl_cipher_des3ctr(mbuf_src, dst,
 				op->sym->cipher.data.offset, iv,
@@ -1441,7 +1484,7 @@ process_openssl_docsis_bpi_op(struct rte_crypto_op *op,
 			/* Encrypt with the block aligned stream with CBC mode */
 			status = process_openssl_cipher_encrypt(mbuf_src, dst,
 					op->sym->cipher.data.offset, iv,
-					srclen, sess->cipher.ctx);
+					srclen, sess->cipher.ctx, 0);
 			if (last_block_len) {
 				/* Point at last block */
 				dst += srclen;
@@ -1491,7 +1534,7 @@ process_openssl_docsis_bpi_op(struct rte_crypto_op *op,
 			/* Decrypt with CBC mode */
 			status |= process_openssl_cipher_decrypt(mbuf_src, dst,
 					op->sym->cipher.data.offset, iv,
-					srclen, sess->cipher.ctx);
+					srclen, sess->cipher.ctx, 0);
 		}
 	}
 
@@ -2121,6 +2164,7 @@ cryptodev_openssl_create(const char *name,
 	dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
 			RTE_CRYPTODEV_FF_CPU_AESNI |
+			RTE_CRYPTODEV_FF_IN_PLACE_SGL |
 			RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT |
 			RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT |
 			RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO |
-- 
2.17.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dpdk-dev] [EXT] [PATCH] crypto/openssl: support SG for inplace buffers
  2019-09-02 12:42 [dpdk-dev] [PATCH] crypto/openssl: support SG for inplace buffers Akhil Goyal
@ 2019-09-13  5:58 ` Anoob Joseph
  2019-09-19 15:57   ` Akhil Goyal
  2019-11-18 13:36 ` [dpdk-dev] [PATCH v2] " Akhil Goyal
  1 sibling, 1 reply; 10+ messages in thread
From: Anoob Joseph @ 2019-09-13  5:58 UTC (permalink / raw)
  To: Akhil Goyal, dev
  Cc: hemant.agrawal, Jerin Jacob Kollanukkaran, declan.doherty,
	konstantin.ananyev, Narayana Prasad Raju Athreya

Hi Akhil,

Please see inline.

Thanks,
Anoob

> -----Original Message-----
> From: Akhil Goyal <akhil.goyal@nxp.com>
> Sent: Monday, September 2, 2019 6:13 PM
> To: dev@dpdk.org
> Cc: hemant.agrawal@nxp.com; Anoob Joseph <anoobj@marvell.com>; Jerin
> Jacob Kollanukkaran <jerinj@marvell.com>; declan.doherty@intel.com;
> konstantin.ananyev@intel.com; Akhil Goyal <akhil.goyal@nxp.com>
> Subject: [EXT] [PATCH] crypto/openssl: support SG for inplace buffers
> 
> External Email
> 
> ----------------------------------------------------------------------
> As per current support, scatter Gather is only supported for out of place input

[Anoob] s/scatter/Scatter
 
> and output buffers.
> This patch add support for scatter gather for inplace buffers.
> 
> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
> ---
>  doc/guides/cryptodevs/features/openssl.ini |  1 +
>  drivers/crypto/openssl/rte_openssl_pmd.c   | 82 +++++++++++++++++-----
>  2 files changed, 64 insertions(+), 19 deletions(-)
> 
> diff --git a/doc/guides/cryptodevs/features/openssl.ini
> b/doc/guides/cryptodevs/features/openssl.ini
> index 6ddca39e7..30ffb111d 100644
> --- a/doc/guides/cryptodevs/features/openssl.ini
> +++ b/doc/guides/cryptodevs/features/openssl.ini
> @@ -6,6 +6,7 @@
>  [Features]
>  Symmetric crypto       = Y
>  Sym operation chaining = Y
> +In Place SGL           = Y
>  OOP SGL In LB  Out     = Y
>  OOP LB  In LB  Out     = Y
>  Asymmetric crypto      = Y
> diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c
> b/drivers/crypto/openssl/rte_openssl_pmd.c
> index 2f5552840..304ebc6ff 100644
> --- a/drivers/crypto/openssl/rte_openssl_pmd.c
> +++ b/drivers/crypto/openssl/rte_openssl_pmd.c
> @@ -798,12 +798,12 @@ get_session(struct openssl_qp *qp, struct
> rte_crypto_op *op)
>   */
>  static inline int
>  process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset,
> -		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx)
> +		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx, uint8_t inplace)
>  {
>  	struct rte_mbuf *m;
>  	int dstlen;
>  	int l, n = srclen;
> -	uint8_t *src;
> +	uint8_t *src, temp[128];

[Anoob] What is 128? Wouldn't a macro be better here?
 
> 
>  	for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
>  			m = m->next)
> @@ -813,6 +813,8 @@ process_openssl_encryption_update(struct rte_mbuf
> *mbuf_src, int offset,
>  		return -1;
> 
>  	src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
> +	if (inplace)
> +		*dst = src;
> 
>  	l = rte_pktmbuf_data_len(m) - offset;
>  	if (srclen <= l) {
> @@ -829,8 +831,24 @@ process_openssl_encryption_update(struct rte_mbuf
> *mbuf_src, int offset,
>  	n -= l;
> 
>  	for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
> +		uint8_t diff = l - dstlen, rem;
> +
>  		src = rte_pktmbuf_mtod(m, uint8_t *);
>  		l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;

[Anoob] Can you explain the logic of below lines? I was trying to understand the two 'rte_memcpy's and how dst is being used there.
 
> +		if (diff && inplace) {
> +			rem = l > (EVP_CIPHER_CTX_block_size(ctx) - diff) ?
> +				(EVP_CIPHER_CTX_block_size(ctx) - diff) : l;

[Anoob] Can't we use RTE_MIN here?
 
> +			if (EVP_EncryptUpdate(ctx, temp,
> +						&dstlen, src, rem) <= 0)
> +				return -1;
> +			n -= rem;
> +			rte_memcpy(*dst, temp, diff);
> +			rte_memcpy(src, temp + diff, rem);
> +			src += rem;
> +			l -= rem;
> +		}
> +		if (inplace)
> +			*dst = src;
>  		if (EVP_EncryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
>  			return -1;
>  		*dst += dstlen;
> @@ -842,12 +860,12 @@ process_openssl_encryption_update(struct rte_mbuf
> *mbuf_src, int offset,
> 
>  static inline int
>  process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset,
> -		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx)
> +		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx, uint8_t inplace)
>  {
>  	struct rte_mbuf *m;
>  	int dstlen;
>  	int l, n = srclen;
> -	uint8_t *src;
> +	uint8_t *src, temp[128];
> 
>  	for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
>  			m = m->next)
> @@ -857,6 +875,8 @@ process_openssl_decryption_update(struct rte_mbuf
> *mbuf_src, int offset,
>  		return -1;
> 
>  	src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
> +	if (inplace)
> +		*dst = src;
> 
>  	l = rte_pktmbuf_data_len(m) - offset;
>  	if (srclen <= l) {
> @@ -873,8 +893,24 @@ process_openssl_decryption_update(struct rte_mbuf
> *mbuf_src, int offset,
>  	n -= l;
> 
>  	for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
> +		uint8_t diff = l - dstlen, rem;
> +
>  		src = rte_pktmbuf_mtod(m, uint8_t *);
>  		l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
> +		if (diff && inplace) {
> +			rem = l > (EVP_CIPHER_CTX_block_size(ctx) - diff) ?
> +				(EVP_CIPHER_CTX_block_size(ctx) - diff) : l;
> +			if (EVP_EncryptUpdate(ctx, temp,
> +						&dstlen, src, rem) <= 0)

[Anoob] Shouldn't this be EVP_DecryptUpdate()? 
 
> +				return -1;
> +			n -= rem;
> +			rte_memcpy(*dst, temp, diff);
> +			rte_memcpy(src, temp + diff, rem);
> +			src += rem;
> +			l -= rem;
> +		}
> +		if (inplace)
> +			*dst = src;
>  		if (EVP_DecryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
>  			return -1;
>  		*dst += dstlen;
> @@ -887,7 +923,8 @@ process_openssl_decryption_update(struct rte_mbuf
> *mbuf_src, int offset,
>  /** Process standard openssl cipher encryption */  static int
> process_openssl_cipher_encrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
> -		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx)
> +		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx,
> +		uint8_t inplace)
>  {
>  	int totlen;
> 
> @@ -897,7 +934,7 @@ process_openssl_cipher_encrypt(struct rte_mbuf
> *mbuf_src, uint8_t *dst,
>  	EVP_CIPHER_CTX_set_padding(ctx, 0);
> 
>  	if (process_openssl_encryption_update(mbuf_src, offset, &dst,
> -			srclen, ctx))
> +			srclen, ctx, inplace))
>  		goto process_cipher_encrypt_err;
> 
>  	if (EVP_EncryptFinal_ex(ctx, dst, &totlen) <= 0) @@ -936,7 +973,8 @@
> process_openssl_cipher_bpi_encrypt(uint8_t *src, uint8_t *dst,
>  /** Process standard openssl cipher decryption */  static int
> process_openssl_cipher_decrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
> -		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx)
> +		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx,
> +		uint8_t inplace)
>  {
>  	int totlen;
> 
> @@ -946,7 +984,7 @@ process_openssl_cipher_decrypt(struct rte_mbuf
> *mbuf_src, uint8_t *dst,
>  	EVP_CIPHER_CTX_set_padding(ctx, 0);
> 
>  	if (process_openssl_decryption_update(mbuf_src, offset, &dst,
> -			srclen, ctx))
> +			srclen, ctx, inplace))
>  		goto process_cipher_decrypt_err;
> 
>  	if (EVP_DecryptFinal_ex(ctx, dst, &totlen) <= 0) @@ -1033,7 +1071,7
> @@ process_openssl_auth_encryption_gcm(struct rte_mbuf *mbuf_src, int
> offset,
> 
>  	if (srclen > 0)
>  		if (process_openssl_encryption_update(mbuf_src, offset, &dst,
> -				srclen, ctx))
> +				srclen, ctx, 0))
>  			goto process_auth_encryption_gcm_err;
> 
>  	/* Workaround open ssl bug in version less then 1.0.1f */ @@ -1078,7
> +1116,7 @@ process_openssl_auth_encryption_ccm(struct rte_mbuf
> *mbuf_src, int offset,
> 
>  	if (srclen > 0)
>  		if (process_openssl_encryption_update(mbuf_src, offset, &dst,
> -				srclen, ctx))
> +				srclen, ctx, 0))
>  			goto process_auth_encryption_ccm_err;
> 
>  	if (EVP_EncryptFinal_ex(ctx, dst, &len) <= 0) @@ -1115,7 +1153,7 @@
> process_openssl_auth_decryption_gcm(struct rte_mbuf *mbuf_src, int offset,
> 
>  	if (srclen > 0)
>  		if (process_openssl_decryption_update(mbuf_src, offset, &dst,
> -				srclen, ctx))
> +				srclen, ctx, 0))
>  			goto process_auth_decryption_gcm_err;
> 
>  	/* Workaround open ssl bug in version less then 1.0.1f */ @@ -1161,7
> +1199,7 @@ process_openssl_auth_decryption_ccm(struct rte_mbuf
> *mbuf_src, int offset,
> 
>  	if (srclen > 0)
>  		if (process_openssl_decryption_update(mbuf_src, offset, &dst,
> -				srclen, ctx))
> +				srclen, ctx, 0))
>  			return -EFAULT;
> 
>  	return 0;
> @@ -1372,12 +1410,15 @@ process_openssl_cipher_op  {
>  	uint8_t *dst, *iv;
>  	int srclen, status;
> +	uint8_t inplace = (mbuf_src == mbuf_dst) ? 1 : 0;
> 
>  	/*
> -	 * Segmented destination buffer is not supported for
> -	 * encryption/decryption
> +	 * Segmented OOP destination buffer is not supported for encryption/
> +	 * decryption. In case of des3ctr, even inplace segmented buffers are
> +	 * not supported.
>  	 */
> -	if (!rte_pktmbuf_is_contiguous(mbuf_dst)) {
> +	if (!rte_pktmbuf_is_contiguous(mbuf_dst) &&
> +			(!inplace || sess->cipher.mode !=
> OPENSSL_CIPHER_LIB)) {
>  		op->status = RTE_CRYPTO_OP_STATUS_ERROR;
>  		return;
>  	}
> @@ -1393,11 +1434,13 @@ process_openssl_cipher_op
>  		if (sess->cipher.direction ==
> RTE_CRYPTO_CIPHER_OP_ENCRYPT)
>  			status = process_openssl_cipher_encrypt(mbuf_src, dst,
>  					op->sym->cipher.data.offset, iv,
> -					srclen, sess->cipher.ctx);
> +					srclen, sess->cipher.ctx,
> +					inplace);
>  		else
>  			status = process_openssl_cipher_decrypt(mbuf_src, dst,
>  					op->sym->cipher.data.offset, iv,
> -					srclen, sess->cipher.ctx);
> +					srclen, sess->cipher.ctx,
> +					inplace);
>  	else
>  		status = process_openssl_cipher_des3ctr(mbuf_src, dst,
>  				op->sym->cipher.data.offset, iv,
> @@ -1441,7 +1484,7 @@ process_openssl_docsis_bpi_op(struct rte_crypto_op
> *op,
>  			/* Encrypt with the block aligned stream with CBC
> mode */
>  			status = process_openssl_cipher_encrypt(mbuf_src, dst,
>  					op->sym->cipher.data.offset, iv,
> -					srclen, sess->cipher.ctx);
> +					srclen, sess->cipher.ctx, 0);
>  			if (last_block_len) {
>  				/* Point at last block */
>  				dst += srclen;
> @@ -1491,7 +1534,7 @@ process_openssl_docsis_bpi_op(struct rte_crypto_op
> *op,
>  			/* Decrypt with CBC mode */
>  			status |= process_openssl_cipher_decrypt(mbuf_src,
> dst,
>  					op->sym->cipher.data.offset, iv,
> -					srclen, sess->cipher.ctx);
> +					srclen, sess->cipher.ctx, 0);
>  		}
>  	}
> 
> @@ -2121,6 +2164,7 @@ cryptodev_openssl_create(const char *name,
>  	dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
>  			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
>  			RTE_CRYPTODEV_FF_CPU_AESNI |
> +			RTE_CRYPTODEV_FF_IN_PLACE_SGL |
>  			RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT |
>  			RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT |
>  			RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO |
> --
> 2.17.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dpdk-dev] [EXT] [PATCH] crypto/openssl: support SG for inplace buffers
  2019-09-13  5:58 ` [dpdk-dev] [EXT] " Anoob Joseph
@ 2019-09-19 15:57   ` Akhil Goyal
  0 siblings, 0 replies; 10+ messages in thread
From: Akhil Goyal @ 2019-09-19 15:57 UTC (permalink / raw)
  To: Anoob Joseph, dev
  Cc: Hemant Agrawal, Jerin Jacob Kollanukkaran, declan.doherty,
	konstantin.ananyev, Narayana Prasad Raju Athreya

Hi Anoob,
> Hi Akhil,
> > As per current support, scatter Gather is only supported for out of place
> input
> 
> [Anoob] s/scatter/Scatter
Ok
> 
> > and output buffers.
> > This patch add support for scatter gather for inplace buffers.
> >
> > Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
> > ---
> >  doc/guides/cryptodevs/features/openssl.ini |  1 +
> >  drivers/crypto/openssl/rte_openssl_pmd.c   | 82 +++++++++++++++++---
> --
> >  2 files changed, 64 insertions(+), 19 deletions(-)
> >
> > diff --git a/doc/guides/cryptodevs/features/openssl.ini
> > b/doc/guides/cryptodevs/features/openssl.ini
> > index 6ddca39e7..30ffb111d 100644
> > --- a/doc/guides/cryptodevs/features/openssl.ini
> > +++ b/doc/guides/cryptodevs/features/openssl.ini
> > @@ -6,6 +6,7 @@
> >  [Features]
> >  Symmetric crypto       = Y
> >  Sym operation chaining = Y
> > +In Place SGL           = Y
> >  OOP SGL In LB  Out     = Y
> >  OOP LB  In LB  Out     = Y
> >  Asymmetric crypto      = Y
> > diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c
> > b/drivers/crypto/openssl/rte_openssl_pmd.c
> > index 2f5552840..304ebc6ff 100644
> > --- a/drivers/crypto/openssl/rte_openssl_pmd.c
> > +++ b/drivers/crypto/openssl/rte_openssl_pmd.c
> > @@ -798,12 +798,12 @@ get_session(struct openssl_qp *qp, struct
> > rte_crypto_op *op)
> >   */
> >  static inline int
> >  process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int
> offset,
> > -		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx)
> > +		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx, uint8_t
> inplace)
> >  {
> >  	struct rte_mbuf *m;
> >  	int dstlen;
> >  	int l, n = srclen;
> > -	uint8_t *src;
> > +	uint8_t *src, temp[128];
> 
> [Anoob] What is 128? Wouldn't a macro be better here?
Will change it to EVP_CIPHER_CTX_block_size . 
> 
> >
> >  	for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
> >  			m = m->next)
> > @@ -813,6 +813,8 @@ process_openssl_encryption_update(struct
> rte_mbuf
> > *mbuf_src, int offset,
> >  		return -1;
> >
> >  	src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
> > +	if (inplace)
> > +		*dst = src;
> >
> >  	l = rte_pktmbuf_data_len(m) - offset;
> >  	if (srclen <= l) {
> > @@ -829,8 +831,24 @@ process_openssl_encryption_update(struct
> rte_mbuf
> > *mbuf_src, int offset,
> >  	n -= l;
> >
> >  	for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
> > +		uint8_t diff = l - dstlen, rem;
> > +
> >  		src = rte_pktmbuf_mtod(m, uint8_t *);
> >  		l = rte_pktmbuf_data_len(m) < n ?
> rte_pktmbuf_data_len(m) : n;
> 
> [Anoob] Can you explain the logic of below lines? I was trying to understand
> the two 'rte_memcpy's and how dst is being used there.

As per the openssl API manual
" EVP_EncryptUpdate() encrypts inl bytes from the buffer in and writes the encrypted version to out. This function can be called multiple times to encrypt successive blocks of data. The amount of data written depends on the block alignment of the encrypted data: as a result the amount of data written may be anything from zero bytes to (inl + cipher_block_size - 1) so out should contain sufficient room. The actual number of bytes written is placed in outl. It also checks if in and out are partially overlapping, and if they are 0 is returned to indicate failure. "

So the problem with SG inline bufs is that if a particular SG is not block aligned, then it will write less data for that SG. So we need to call EVP_EncryptUpdate for the diff bytes of previous SG and take the remaining of the block size from the next SG.
Now we cannot store that in dst as it is,  because it is not a contiguous buffer. So will get the output of EVP_EncryptUpdate to temp and copy diff bytes in previous SG and the remaining bytes to next SG and update pointer accordingly.

> 
> > +		if (diff && inplace) {
> > +			rem = l > (EVP_CIPHER_CTX_block_size(ctx) - diff) ?
> > +				(EVP_CIPHER_CTX_block_size(ctx) - diff) : l;
> 
> [Anoob] Can't we use RTE_MIN here?
Yes will change that.
> 
> > +			if (EVP_EncryptUpdate(ctx, temp,
> > +						&dstlen, src, rem) <= 0)
> > +				return -1;
> > +			n -= rem;
> > +			rte_memcpy(*dst, temp, diff);
> > +			rte_memcpy(src, temp + diff, rem);
> > +			src += rem;
> > +			l -= rem;
> > +		}
> > +		if (inplace)
> > +			*dst = src;
> >  		if (EVP_EncryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
> >  			return -1;
> >  		*dst += dstlen;
> > @@ -842,12 +860,12 @@ process_openssl_encryption_update(struct
> rte_mbuf
> > *mbuf_src, int offset,
> >
> >  static inline int
> >  process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int
> offset,
> > -		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx)
> > +		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx, uint8_t
> inplace)
> >  {
> >  	struct rte_mbuf *m;
> >  	int dstlen;
> >  	int l, n = srclen;
> > -	uint8_t *src;
> > +	uint8_t *src, temp[128];
> >
> >  	for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
> >  			m = m->next)
> > @@ -857,6 +875,8 @@ process_openssl_decryption_update(struct
> rte_mbuf
> > *mbuf_src, int offset,
> >  		return -1;
> >
> >  	src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
> > +	if (inplace)
> > +		*dst = src;
> >
> >  	l = rte_pktmbuf_data_len(m) - offset;
> >  	if (srclen <= l) {
> > @@ -873,8 +893,24 @@ process_openssl_decryption_update(struct
> rte_mbuf
> > *mbuf_src, int offset,
> >  	n -= l;
> >
> >  	for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
> > +		uint8_t diff = l - dstlen, rem;
> > +
> >  		src = rte_pktmbuf_mtod(m, uint8_t *);
> >  		l = rte_pktmbuf_data_len(m) < n ?
> rte_pktmbuf_data_len(m) : n;
> > +		if (diff && inplace) {
> > +			rem = l > (EVP_CIPHER_CTX_block_size(ctx) - diff) ?
> > +				(EVP_CIPHER_CTX_block_size(ctx) - diff) : l;
> > +			if (EVP_EncryptUpdate(ctx, temp,
> > +						&dstlen, src, rem) <= 0)
> 
> [Anoob] Shouldn't this be EVP_DecryptUpdate()?
Yes, good catch.
> 
> > +				return -1;
> > +			n -= rem;
> > +			rte_memcpy(*dst, temp, diff);
> > +			rte_memcpy(src, temp + diff, rem);
> > +			src += rem;
> > +			l -= rem;
> > +		}
> > +		if (inplace)
> > +			*dst = src;
> >  		if (EVP_DecryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
> >  			return -1;
> >  		*dst += dstlen;
> > @@ -887,7 +923,8 @@ process_openssl_decryption_update(struct
> rte_mbuf
> > *mbuf_src, int offset,
> >  /** Process standard openssl cipher encryption */  static int
> > process_openssl_cipher_encrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
> > -		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx)
> > +		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx,
> > +		uint8_t inplace)
> >  {
> >  	int totlen;
> >
> > @@ -897,7 +934,7 @@ process_openssl_cipher_encrypt(struct rte_mbuf
> > *mbuf_src, uint8_t *dst,
> >  	EVP_CIPHER_CTX_set_padding(ctx, 0);
> >
> >  	if (process_openssl_encryption_update(mbuf_src, offset, &dst,
> > -			srclen, ctx))
> > +			srclen, ctx, inplace))
> >  		goto process_cipher_encrypt_err;
> >
> >  	if (EVP_EncryptFinal_ex(ctx, dst, &totlen) <= 0) @@ -936,7 +973,8
> @@
> > process_openssl_cipher_bpi_encrypt(uint8_t *src, uint8_t *dst,
> >  /** Process standard openssl cipher decryption */  static int
> > process_openssl_cipher_decrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
> > -		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx)
> > +		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx,
> > +		uint8_t inplace)
> >  {
> >  	int totlen;
> >
> > @@ -946,7 +984,7 @@ process_openssl_cipher_decrypt(struct rte_mbuf
> > *mbuf_src, uint8_t *dst,
> >  	EVP_CIPHER_CTX_set_padding(ctx, 0);
> >
> >  	if (process_openssl_decryption_update(mbuf_src, offset, &dst,
> > -			srclen, ctx))
> > +			srclen, ctx, inplace))
> >  		goto process_cipher_decrypt_err;
> >
> >  	if (EVP_DecryptFinal_ex(ctx, dst, &totlen) <= 0) @@ -1033,7 +1071,7
> > @@ process_openssl_auth_encryption_gcm(struct rte_mbuf *mbuf_src,
> int
> > offset,
> >
> >  	if (srclen > 0)
> >  		if (process_openssl_encryption_update(mbuf_src, offset,
> &dst,
> > -				srclen, ctx))
> > +				srclen, ctx, 0))
> >  			goto process_auth_encryption_gcm_err;
> >
> >  	/* Workaround open ssl bug in version less then 1.0.1f */ @@ -
> 1078,7
> > +1116,7 @@ process_openssl_auth_encryption_ccm(struct rte_mbuf
> > *mbuf_src, int offset,
> >
> >  	if (srclen > 0)
> >  		if (process_openssl_encryption_update(mbuf_src, offset,
> &dst,
> > -				srclen, ctx))
> > +				srclen, ctx, 0))
> >  			goto process_auth_encryption_ccm_err;
> >
> >  	if (EVP_EncryptFinal_ex(ctx, dst, &len) <= 0) @@ -1115,7 +1153,7
> @@
> > process_openssl_auth_decryption_gcm(struct rte_mbuf *mbuf_src, int
> offset,
> >
> >  	if (srclen > 0)
> >  		if (process_openssl_decryption_update(mbuf_src, offset,
> &dst,
> > -				srclen, ctx))
> > +				srclen, ctx, 0))
> >  			goto process_auth_decryption_gcm_err;
> >
> >  	/* Workaround open ssl bug in version less then 1.0.1f */ @@ -
> 1161,7
> > +1199,7 @@ process_openssl_auth_decryption_ccm(struct rte_mbuf
> > *mbuf_src, int offset,
> >
> >  	if (srclen > 0)
> >  		if (process_openssl_decryption_update(mbuf_src, offset,
> &dst,
> > -				srclen, ctx))
> > +				srclen, ctx, 0))
> >  			return -EFAULT;
> >
> >  	return 0;
> > @@ -1372,12 +1410,15 @@ process_openssl_cipher_op  {
> >  	uint8_t *dst, *iv;
> >  	int srclen, status;
> > +	uint8_t inplace = (mbuf_src == mbuf_dst) ? 1 : 0;
> >
> >  	/*
> > -	 * Segmented destination buffer is not supported for
> > -	 * encryption/decryption
> > +	 * Segmented OOP destination buffer is not supported for
> encryption/
> > +	 * decryption. In case of des3ctr, even inplace segmented buffers are
> > +	 * not supported.
> >  	 */
> > -	if (!rte_pktmbuf_is_contiguous(mbuf_dst)) {
> > +	if (!rte_pktmbuf_is_contiguous(mbuf_dst) &&
> > +			(!inplace || sess->cipher.mode !=
> > OPENSSL_CIPHER_LIB)) {
> >  		op->status = RTE_CRYPTO_OP_STATUS_ERROR;
> >  		return;
> >  	}
> > @@ -1393,11 +1434,13 @@ process_openssl_cipher_op
> >  		if (sess->cipher.direction ==
> > RTE_CRYPTO_CIPHER_OP_ENCRYPT)
> >  			status = process_openssl_cipher_encrypt(mbuf_src,
> dst,
> >  					op->sym->cipher.data.offset, iv,
> > -					srclen, sess->cipher.ctx);
> > +					srclen, sess->cipher.ctx,
> > +					inplace);
> >  		else
> >  			status = process_openssl_cipher_decrypt(mbuf_src,
> dst,
> >  					op->sym->cipher.data.offset, iv,
> > -					srclen, sess->cipher.ctx);
> > +					srclen, sess->cipher.ctx,
> > +					inplace);
> >  	else
> >  		status = process_openssl_cipher_des3ctr(mbuf_src, dst,
> >  				op->sym->cipher.data.offset, iv,
> > @@ -1441,7 +1484,7 @@ process_openssl_docsis_bpi_op(struct
> rte_crypto_op
> > *op,
> >  			/* Encrypt with the block aligned stream with CBC
> > mode */
> >  			status = process_openssl_cipher_encrypt(mbuf_src,
> dst,
> >  					op->sym->cipher.data.offset, iv,
> > -					srclen, sess->cipher.ctx);
> > +					srclen, sess->cipher.ctx, 0);
> >  			if (last_block_len) {
> >  				/* Point at last block */
> >  				dst += srclen;
> > @@ -1491,7 +1534,7 @@ process_openssl_docsis_bpi_op(struct
> rte_crypto_op
> > *op,
> >  			/* Decrypt with CBC mode */
> >  			status |= process_openssl_cipher_decrypt(mbuf_src,
> > dst,
> >  					op->sym->cipher.data.offset, iv,
> > -					srclen, sess->cipher.ctx);
> > +					srclen, sess->cipher.ctx, 0);
> >  		}
> >  	}
> >
> > @@ -2121,6 +2164,7 @@ cryptodev_openssl_create(const char *name,
> >  	dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
> >  			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
> >  			RTE_CRYPTODEV_FF_CPU_AESNI |
> > +			RTE_CRYPTODEV_FF_IN_PLACE_SGL |
> >  			RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT |
> >  			RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT |
> >  			RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO |
> > --
> > 2.17.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dpdk-dev] [PATCH v2] crypto/openssl: support SG for inplace buffers
  2019-09-02 12:42 [dpdk-dev] [PATCH] crypto/openssl: support SG for inplace buffers Akhil Goyal
  2019-09-13  5:58 ` [dpdk-dev] [EXT] " Anoob Joseph
@ 2019-11-18 13:36 ` Akhil Goyal
  2019-11-19 14:19   ` Akhil Goyal
                     ` (2 more replies)
  1 sibling, 3 replies; 10+ messages in thread
From: Akhil Goyal @ 2019-11-18 13:36 UTC (permalink / raw)
  To: dev; +Cc: declan.doherty, anoobj, konstantin.ananyev, jerinj, Akhil Goyal

As per current support, Scatter Gather is only supported
for out of place input and output buffers.
This patch add support for Scatter Gather for inplace buffers.

Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
---
changes in v2:
- fixed typo
- enabled corresponding test case
- removed hardcodings


 app/test/test_cryptodev_aes_test_vectors.h |  2 +
 doc/guides/cryptodevs/features/openssl.ini |  1 +
 drivers/crypto/openssl/rte_openssl_pmd.c   | 84 ++++++++++++++++------
 3 files changed, 66 insertions(+), 21 deletions(-)

diff --git a/app/test/test_cryptodev_aes_test_vectors.h b/app/test/test_cryptodev_aes_test_vectors.h
index 9afa3aef8..8307fcf9a 100644
--- a/app/test/test_cryptodev_aes_test_vectors.h
+++ b/app/test/test_cryptodev_aes_test_vectors.h
@@ -1773,6 +1773,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = {
 			    BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR |
 			    BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX |
 			    BLOCKCIPHER_TEST_TARGET_PMD_NITROX |
+			    BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
 			    BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX2
 	},
 	{
@@ -2248,6 +2249,7 @@ static const struct blockcipher_test_case aes_cipheronly_test_cases[] = {
 			BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC |
 			BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR |
 			BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX |
+			BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
 			BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX2
 	},
 	{
diff --git a/doc/guides/cryptodevs/features/openssl.ini b/doc/guides/cryptodevs/features/openssl.ini
index 6ddca39e7..30ffb111d 100644
--- a/doc/guides/cryptodevs/features/openssl.ini
+++ b/doc/guides/cryptodevs/features/openssl.ini
@@ -6,6 +6,7 @@
 [Features]
 Symmetric crypto       = Y
 Sym operation chaining = Y
+In Place SGL           = Y
 OOP SGL In LB  Out     = Y
 OOP LB  In LB  Out     = Y
 Asymmetric crypto      = Y
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index d68713e7e..369ad1aa7 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -798,12 +798,12 @@ get_session(struct openssl_qp *qp, struct rte_crypto_op *op)
  */
 static inline int
 process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset,
-		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx)
+		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx, uint8_t inplace)
 {
 	struct rte_mbuf *m;
 	int dstlen;
 	int l, n = srclen;
-	uint8_t *src;
+	uint8_t *src, temp[EVP_CIPHER_CTX_block_size(ctx)];
 
 	for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
 			m = m->next)
@@ -813,6 +813,8 @@ process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset,
 		return -1;
 
 	src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
+	if (inplace)
+		*dst = src;
 
 	l = rte_pktmbuf_data_len(m) - offset;
 	if (srclen <= l) {
@@ -829,8 +831,24 @@ process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset,
 	n -= l;
 
 	for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
+		uint8_t diff = l - dstlen, rem;
+
 		src = rte_pktmbuf_mtod(m, uint8_t *);
-		l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
+		l = RTE_MIN(rte_pktmbuf_data_len(m), n);
+		if (diff && inplace) {
+			rem = RTE_MIN(l,
+				(EVP_CIPHER_CTX_block_size(ctx) - diff));
+			if (EVP_EncryptUpdate(ctx, temp,
+						&dstlen, src, rem) <= 0)
+				return -1;
+			n -= rem;
+			rte_memcpy(*dst, temp, diff);
+			rte_memcpy(src, temp + diff, rem);
+			src += rem;
+			l -= rem;
+		}
+		if (inplace)
+			*dst = src;
 		if (EVP_EncryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
 			return -1;
 		*dst += dstlen;
@@ -842,12 +860,12 @@ process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset,
 
 static inline int
 process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset,
-		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx)
+		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx, uint8_t inplace)
 {
 	struct rte_mbuf *m;
 	int dstlen;
 	int l, n = srclen;
-	uint8_t *src;
+	uint8_t *src, temp[128];
 
 	for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
 			m = m->next)
@@ -857,6 +875,8 @@ process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset,
 		return -1;
 
 	src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
+	if (inplace)
+		*dst = src;
 
 	l = rte_pktmbuf_data_len(m) - offset;
 	if (srclen <= l) {
@@ -873,8 +893,24 @@ process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset,
 	n -= l;
 
 	for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
+		uint8_t diff = l - dstlen, rem;
+
 		src = rte_pktmbuf_mtod(m, uint8_t *);
-		l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
+		l = RTE_MIN(rte_pktmbuf_data_len(m), n);
+		if (diff && inplace) {
+			rem = RTE_MIN(l,
+				(EVP_CIPHER_CTX_block_size(ctx) - diff));
+			if (EVP_DecryptUpdate(ctx, temp,
+						&dstlen, src, rem) <= 0)
+				return -1;
+			n -= rem;
+			rte_memcpy(*dst, temp, diff);
+			rte_memcpy(src, temp + diff, rem);
+			src += rem;
+			l -= rem;
+		}
+		if (inplace)
+			*dst = src;
 		if (EVP_DecryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
 			return -1;
 		*dst += dstlen;
@@ -887,7 +923,8 @@ process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset,
 /** Process standard openssl cipher encryption */
 static int
 process_openssl_cipher_encrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
-		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx)
+		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx,
+		uint8_t inplace)
 {
 	int totlen;
 
@@ -897,7 +934,7 @@ process_openssl_cipher_encrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
 	EVP_CIPHER_CTX_set_padding(ctx, 0);
 
 	if (process_openssl_encryption_update(mbuf_src, offset, &dst,
-			srclen, ctx))
+			srclen, ctx, inplace))
 		goto process_cipher_encrypt_err;
 
 	if (EVP_EncryptFinal_ex(ctx, dst, &totlen) <= 0)
@@ -936,7 +973,8 @@ process_openssl_cipher_bpi_encrypt(uint8_t *src, uint8_t *dst,
 /** Process standard openssl cipher decryption */
 static int
 process_openssl_cipher_decrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
-		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx)
+		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx,
+		uint8_t inplace)
 {
 	int totlen;
 
@@ -946,7 +984,7 @@ process_openssl_cipher_decrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
 	EVP_CIPHER_CTX_set_padding(ctx, 0);
 
 	if (process_openssl_decryption_update(mbuf_src, offset, &dst,
-			srclen, ctx))
+			srclen, ctx, inplace))
 		goto process_cipher_decrypt_err;
 
 	if (EVP_DecryptFinal_ex(ctx, dst, &totlen) <= 0)
@@ -1033,7 +1071,7 @@ process_openssl_auth_encryption_gcm(struct rte_mbuf *mbuf_src, int offset,
 
 	if (srclen > 0)
 		if (process_openssl_encryption_update(mbuf_src, offset, &dst,
-				srclen, ctx))
+				srclen, ctx, 0))
 			goto process_auth_encryption_gcm_err;
 
 	/* Workaround open ssl bug in version less then 1.0.1f */
@@ -1078,7 +1116,7 @@ process_openssl_auth_encryption_ccm(struct rte_mbuf *mbuf_src, int offset,
 
 	if (srclen > 0)
 		if (process_openssl_encryption_update(mbuf_src, offset, &dst,
-				srclen, ctx))
+				srclen, ctx, 0))
 			goto process_auth_encryption_ccm_err;
 
 	if (EVP_EncryptFinal_ex(ctx, dst, &len) <= 0)
@@ -1115,7 +1153,7 @@ process_openssl_auth_decryption_gcm(struct rte_mbuf *mbuf_src, int offset,
 
 	if (srclen > 0)
 		if (process_openssl_decryption_update(mbuf_src, offset, &dst,
-				srclen, ctx))
+				srclen, ctx, 0))
 			goto process_auth_decryption_gcm_err;
 
 	/* Workaround open ssl bug in version less then 1.0.1f */
@@ -1161,7 +1199,7 @@ process_openssl_auth_decryption_ccm(struct rte_mbuf *mbuf_src, int offset,
 
 	if (srclen > 0)
 		if (process_openssl_decryption_update(mbuf_src, offset, &dst,
-				srclen, ctx))
+				srclen, ctx, 0))
 			return -EFAULT;
 
 	return 0;
@@ -1376,13 +1414,16 @@ process_openssl_cipher_op
 {
 	uint8_t *dst, *iv;
 	int srclen, status;
+	uint8_t inplace = (mbuf_src == mbuf_dst) ? 1 : 0;
 	EVP_CIPHER_CTX *ctx_copy;
 
 	/*
-	 * Segmented destination buffer is not supported for
-	 * encryption/decryption
+	 * Segmented OOP destination buffer is not supported for encryption/
+	 * decryption. In case of des3ctr, even inplace segmented buffers are
+	 * not supported.
 	 */
-	if (!rte_pktmbuf_is_contiguous(mbuf_dst)) {
+	if (!rte_pktmbuf_is_contiguous(mbuf_dst) &&
+			(!inplace || sess->cipher.mode != OPENSSL_CIPHER_LIB)) {
 		op->status = RTE_CRYPTO_OP_STATUS_ERROR;
 		return;
 	}
@@ -1400,11 +1441,11 @@ process_openssl_cipher_op
 		if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
 			status = process_openssl_cipher_encrypt(mbuf_src, dst,
 					op->sym->cipher.data.offset, iv,
-					srclen, ctx_copy);
+					srclen, ctx_copy, inplace);
 		else
 			status = process_openssl_cipher_decrypt(mbuf_src, dst,
 					op->sym->cipher.data.offset, iv,
-					srclen, ctx_copy);
+					srclen, ctx_copy, inplace);
 	else
 		status = process_openssl_cipher_des3ctr(mbuf_src, dst,
 				op->sym->cipher.data.offset, iv,
@@ -1449,7 +1490,7 @@ process_openssl_docsis_bpi_op(struct rte_crypto_op *op,
 			/* Encrypt with the block aligned stream with CBC mode */
 			status = process_openssl_cipher_encrypt(mbuf_src, dst,
 					op->sym->cipher.data.offset, iv,
-					srclen, sess->cipher.ctx);
+					srclen, sess->cipher.ctx, 0);
 			if (last_block_len) {
 				/* Point at last block */
 				dst += srclen;
@@ -1499,7 +1540,7 @@ process_openssl_docsis_bpi_op(struct rte_crypto_op *op,
 			/* Decrypt with CBC mode */
 			status |= process_openssl_cipher_decrypt(mbuf_src, dst,
 					op->sym->cipher.data.offset, iv,
-					srclen, sess->cipher.ctx);
+					srclen, sess->cipher.ctx, 0);
 		}
 	}
 
@@ -2137,6 +2178,7 @@ cryptodev_openssl_create(const char *name,
 	dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
 			RTE_CRYPTODEV_FF_CPU_AESNI |
+			RTE_CRYPTODEV_FF_IN_PLACE_SGL |
 			RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT |
 			RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT |
 			RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO |
-- 
2.17.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dpdk-dev] [PATCH v2] crypto/openssl: support SG for inplace buffers
  2019-11-18 13:36 ` [dpdk-dev] [PATCH v2] " Akhil Goyal
@ 2019-11-19 14:19   ` Akhil Goyal
  2019-11-20  4:31   ` [dpdk-dev] [EXT] " Anoob Joseph
  2019-11-20  5:58   ` [dpdk-dev] [PATCH v3] " Akhil Goyal
  2 siblings, 0 replies; 10+ messages in thread
From: Akhil Goyal @ 2019-11-19 14:19 UTC (permalink / raw)
  To: anoobj; +Cc: declan.doherty, konstantin.ananyev, jerinj, dev, Akhil Goyal

Hi Anoob,

Any more comments on this patch?
If not please Ack.

Thanks,
Akhil
> 
> As per current support, Scatter Gather is only supported
> for out of place input and output buffers.
> This patch add support for Scatter Gather for inplace buffers.
> 
> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
> ---


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dpdk-dev] [EXT] [PATCH v2] crypto/openssl: support SG for inplace buffers
  2019-11-18 13:36 ` [dpdk-dev] [PATCH v2] " Akhil Goyal
  2019-11-19 14:19   ` Akhil Goyal
@ 2019-11-20  4:31   ` Anoob Joseph
  2019-11-20  6:11     ` Akhil Goyal
  2019-11-20  5:58   ` [dpdk-dev] [PATCH v3] " Akhil Goyal
  2 siblings, 1 reply; 10+ messages in thread
From: Anoob Joseph @ 2019-11-20  4:31 UTC (permalink / raw)
  To: Akhil Goyal, dev
  Cc: declan.doherty, konstantin.ananyev, Jerin Jacob Kollanukkaran

Hi Akhil,

A minor question. Otherwise, looks good.

Thanks,
Anoob

> -----Original Message-----
> From: Akhil Goyal <akhil.goyal@nxp.com>
> Sent: Monday, November 18, 2019 7:06 PM
> To: dev@dpdk.org
> Cc: declan.doherty@intel.com; Anoob Joseph <anoobj@marvell.com>;
> konstantin.ananyev@intel.com; Jerin Jacob Kollanukkaran
> <jerinj@marvell.com>; Akhil Goyal <akhil.goyal@nxp.com>
> Subject: [EXT] [PATCH v2] crypto/openssl: support SG for inplace buffers
> 
> External Email
> 
> ----------------------------------------------------------------------
> As per current support, Scatter Gather is only supported for out of place input
> and output buffers.
> This patch add support for Scatter Gather for inplace buffers.
> 
> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
> ---
> changes in v2:
> - fixed typo
> - enabled corresponding test case
> - removed hardcodings
> 
> 
>  app/test/test_cryptodev_aes_test_vectors.h |  2 +
> doc/guides/cryptodevs/features/openssl.ini |  1 +
>  drivers/crypto/openssl/rte_openssl_pmd.c   | 84 ++++++++++++++++------
>  3 files changed, 66 insertions(+), 21 deletions(-)
> 
> diff --git a/app/test/test_cryptodev_aes_test_vectors.h
> b/app/test/test_cryptodev_aes_test_vectors.h
> index 9afa3aef8..8307fcf9a 100644
> --- a/app/test/test_cryptodev_aes_test_vectors.h
> +++ b/app/test/test_cryptodev_aes_test_vectors.h
> @@ -1773,6 +1773,7 @@ static const struct blockcipher_test_case
> aes_chain_test_cases[] = {
>  			    BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR |
>  			    BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX |
>  			    BLOCKCIPHER_TEST_TARGET_PMD_NITROX |
> +			    BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
>  			    BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX2
>  	},
>  	{
> @@ -2248,6 +2249,7 @@ static const struct blockcipher_test_case
> aes_cipheronly_test_cases[] = {
>  			BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC |
>  			BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR |
>  			BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX |
> +			BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
>  			BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX2
>  	},
>  	{
> diff --git a/doc/guides/cryptodevs/features/openssl.ini
> b/doc/guides/cryptodevs/features/openssl.ini
> index 6ddca39e7..30ffb111d 100644
> --- a/doc/guides/cryptodevs/features/openssl.ini
> +++ b/doc/guides/cryptodevs/features/openssl.ini
> @@ -6,6 +6,7 @@
>  [Features]
>  Symmetric crypto       = Y
>  Sym operation chaining = Y
> +In Place SGL           = Y
>  OOP SGL In LB  Out     = Y
>  OOP LB  In LB  Out     = Y
>  Asymmetric crypto      = Y
> diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c
> b/drivers/crypto/openssl/rte_openssl_pmd.c
> index d68713e7e..369ad1aa7 100644
> --- a/drivers/crypto/openssl/rte_openssl_pmd.c
> +++ b/drivers/crypto/openssl/rte_openssl_pmd.c
> @@ -798,12 +798,12 @@ get_session(struct openssl_qp *qp, struct
> rte_crypto_op *op)
>   */
>  static inline int
>  process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset,
> -		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx)
> +		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx, uint8_t inplace)
>  {
>  	struct rte_mbuf *m;
>  	int dstlen;
>  	int l, n = srclen;
> -	uint8_t *src;
> +	uint8_t *src, temp[EVP_CIPHER_CTX_block_size(ctx)];
> 
>  	for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
>  			m = m->next)
> @@ -813,6 +813,8 @@ process_openssl_encryption_update(struct rte_mbuf
> *mbuf_src, int offset,
>  		return -1;
> 
>  	src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
> +	if (inplace)
> +		*dst = src;
> 
>  	l = rte_pktmbuf_data_len(m) - offset;
>  	if (srclen <= l) {
> @@ -829,8 +831,24 @@ process_openssl_encryption_update(struct rte_mbuf
> *mbuf_src, int offset,
>  	n -= l;
> 
>  	for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
> +		uint8_t diff = l - dstlen, rem;
> +
>  		src = rte_pktmbuf_mtod(m, uint8_t *);
> -		l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
> +		l = RTE_MIN(rte_pktmbuf_data_len(m), n);
> +		if (diff && inplace) {
> +			rem = RTE_MIN(l,
> +				(EVP_CIPHER_CTX_block_size(ctx) - diff));
> +			if (EVP_EncryptUpdate(ctx, temp,
> +						&dstlen, src, rem) <= 0)
> +				return -1;
> +			n -= rem;
> +			rte_memcpy(*dst, temp, diff);
> +			rte_memcpy(src, temp + diff, rem);
> +			src += rem;
> +			l -= rem;
> +		}
> +		if (inplace)
> +			*dst = src;
>  		if (EVP_EncryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
>  			return -1;
>  		*dst += dstlen;
> @@ -842,12 +860,12 @@ process_openssl_encryption_update(struct rte_mbuf
> *mbuf_src, int offset,
> 
>  static inline int
>  process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset,
> -		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx)
> +		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx, uint8_t inplace)
>  {
>  	struct rte_mbuf *m;
>  	int dstlen;
>  	int l, n = srclen;
> -	uint8_t *src;
> +	uint8_t *src, temp[128];

[Anoob] In case of encrypt_update, the buffer is 'temp[EVP_CIPHER_CTX_block_size(ctx)]'. Is the above intentional?

> 
>  	for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
>  			m = m->next)
> @@ -857,6 +875,8 @@ process_openssl_decryption_update(struct rte_mbuf
> *mbuf_src, int offset,
>  		return -1;
> 
>  	src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
> +	if (inplace)
> +		*dst = src;
> 
>  	l = rte_pktmbuf_data_len(m) - offset;
>  	if (srclen <= l) {
> @@ -873,8 +893,24 @@ process_openssl_decryption_update(struct rte_mbuf
> *mbuf_src, int offset,
>  	n -= l;
> 
>  	for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
> +		uint8_t diff = l - dstlen, rem;
> +
>  		src = rte_pktmbuf_mtod(m, uint8_t *);
> -		l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
> +		l = RTE_MIN(rte_pktmbuf_data_len(m), n);
> +		if (diff && inplace) {
> +			rem = RTE_MIN(l,
> +				(EVP_CIPHER_CTX_block_size(ctx) - diff));
> +			if (EVP_DecryptUpdate(ctx, temp,
> +						&dstlen, src, rem) <= 0)
> +				return -1;
> +			n -= rem;
> +			rte_memcpy(*dst, temp, diff);
> +			rte_memcpy(src, temp + diff, rem);
> +			src += rem;
> +			l -= rem;
> +		}
> +		if (inplace)
> +			*dst = src;
>  		if (EVP_DecryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
>  			return -1;
>  		*dst += dstlen;
> @@ -887,7 +923,8 @@ process_openssl_decryption_update(struct rte_mbuf
> *mbuf_src, int offset,
>  /** Process standard openssl cipher encryption */  static int
> process_openssl_cipher_encrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
> -		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx)
> +		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx,
> +		uint8_t inplace)
>  {
>  	int totlen;
> 
> @@ -897,7 +934,7 @@ process_openssl_cipher_encrypt(struct rte_mbuf
> *mbuf_src, uint8_t *dst,
>  	EVP_CIPHER_CTX_set_padding(ctx, 0);
> 
>  	if (process_openssl_encryption_update(mbuf_src, offset, &dst,
> -			srclen, ctx))
> +			srclen, ctx, inplace))
>  		goto process_cipher_encrypt_err;
> 
>  	if (EVP_EncryptFinal_ex(ctx, dst, &totlen) <= 0) @@ -936,7 +973,8 @@
> process_openssl_cipher_bpi_encrypt(uint8_t *src, uint8_t *dst,
>  /** Process standard openssl cipher decryption */  static int
> process_openssl_cipher_decrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
> -		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx)
> +		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx,
> +		uint8_t inplace)
>  {
>  	int totlen;
> 
> @@ -946,7 +984,7 @@ process_openssl_cipher_decrypt(struct rte_mbuf
> *mbuf_src, uint8_t *dst,
>  	EVP_CIPHER_CTX_set_padding(ctx, 0);
> 
>  	if (process_openssl_decryption_update(mbuf_src, offset, &dst,
> -			srclen, ctx))
> +			srclen, ctx, inplace))
>  		goto process_cipher_decrypt_err;
> 
>  	if (EVP_DecryptFinal_ex(ctx, dst, &totlen) <= 0) @@ -1033,7 +1071,7
> @@ process_openssl_auth_encryption_gcm(struct rte_mbuf *mbuf_src, int
> offset,
> 
>  	if (srclen > 0)
>  		if (process_openssl_encryption_update(mbuf_src, offset, &dst,
> -				srclen, ctx))
> +				srclen, ctx, 0))
>  			goto process_auth_encryption_gcm_err;
> 
>  	/* Workaround open ssl bug in version less then 1.0.1f */ @@ -1078,7
> +1116,7 @@ process_openssl_auth_encryption_ccm(struct rte_mbuf
> *mbuf_src, int offset,
> 
>  	if (srclen > 0)
>  		if (process_openssl_encryption_update(mbuf_src, offset, &dst,
> -				srclen, ctx))
> +				srclen, ctx, 0))
>  			goto process_auth_encryption_ccm_err;
> 
>  	if (EVP_EncryptFinal_ex(ctx, dst, &len) <= 0) @@ -1115,7 +1153,7 @@
> process_openssl_auth_decryption_gcm(struct rte_mbuf *mbuf_src, int offset,
> 
>  	if (srclen > 0)
>  		if (process_openssl_decryption_update(mbuf_src, offset, &dst,
> -				srclen, ctx))
> +				srclen, ctx, 0))
>  			goto process_auth_decryption_gcm_err;
> 
>  	/* Workaround open ssl bug in version less then 1.0.1f */ @@ -1161,7
> +1199,7 @@ process_openssl_auth_decryption_ccm(struct rte_mbuf
> *mbuf_src, int offset,
> 
>  	if (srclen > 0)
>  		if (process_openssl_decryption_update(mbuf_src, offset, &dst,
> -				srclen, ctx))
> +				srclen, ctx, 0))
>  			return -EFAULT;
> 
>  	return 0;
> @@ -1376,13 +1414,16 @@ process_openssl_cipher_op  {
>  	uint8_t *dst, *iv;
>  	int srclen, status;
> +	uint8_t inplace = (mbuf_src == mbuf_dst) ? 1 : 0;
>  	EVP_CIPHER_CTX *ctx_copy;
> 
>  	/*
> -	 * Segmented destination buffer is not supported for
> -	 * encryption/decryption
> +	 * Segmented OOP destination buffer is not supported for encryption/
> +	 * decryption. In case of des3ctr, even inplace segmented buffers are
> +	 * not supported.
>  	 */
> -	if (!rte_pktmbuf_is_contiguous(mbuf_dst)) {
> +	if (!rte_pktmbuf_is_contiguous(mbuf_dst) &&
> +			(!inplace || sess->cipher.mode !=
> OPENSSL_CIPHER_LIB)) {
>  		op->status = RTE_CRYPTO_OP_STATUS_ERROR;
>  		return;
>  	}
> @@ -1400,11 +1441,11 @@ process_openssl_cipher_op
>  		if (sess->cipher.direction ==
> RTE_CRYPTO_CIPHER_OP_ENCRYPT)
>  			status = process_openssl_cipher_encrypt(mbuf_src, dst,
>  					op->sym->cipher.data.offset, iv,
> -					srclen, ctx_copy);
> +					srclen, ctx_copy, inplace);
>  		else
>  			status = process_openssl_cipher_decrypt(mbuf_src, dst,
>  					op->sym->cipher.data.offset, iv,
> -					srclen, ctx_copy);
> +					srclen, ctx_copy, inplace);
>  	else
>  		status = process_openssl_cipher_des3ctr(mbuf_src, dst,
>  				op->sym->cipher.data.offset, iv,
> @@ -1449,7 +1490,7 @@ process_openssl_docsis_bpi_op(struct rte_crypto_op
> *op,
>  			/* Encrypt with the block aligned stream with CBC
> mode */
>  			status = process_openssl_cipher_encrypt(mbuf_src, dst,
>  					op->sym->cipher.data.offset, iv,
> -					srclen, sess->cipher.ctx);
> +					srclen, sess->cipher.ctx, 0);
>  			if (last_block_len) {
>  				/* Point at last block */
>  				dst += srclen;
> @@ -1499,7 +1540,7 @@ process_openssl_docsis_bpi_op(struct rte_crypto_op
> *op,
>  			/* Decrypt with CBC mode */
>  			status |= process_openssl_cipher_decrypt(mbuf_src,
> dst,
>  					op->sym->cipher.data.offset, iv,
> -					srclen, sess->cipher.ctx);
> +					srclen, sess->cipher.ctx, 0);
>  		}
>  	}
> 
> @@ -2137,6 +2178,7 @@ cryptodev_openssl_create(const char *name,
>  	dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
>  			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
>  			RTE_CRYPTODEV_FF_CPU_AESNI |
> +			RTE_CRYPTODEV_FF_IN_PLACE_SGL |
>  			RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT |
>  			RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT |
>  			RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO |
> --
> 2.17.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [dpdk-dev] [PATCH v3] crypto/openssl: support SG for inplace buffers
  2019-11-18 13:36 ` [dpdk-dev] [PATCH v2] " Akhil Goyal
  2019-11-19 14:19   ` Akhil Goyal
  2019-11-20  4:31   ` [dpdk-dev] [EXT] " Anoob Joseph
@ 2019-11-20  5:58   ` Akhil Goyal
  2019-11-20  6:23     ` Anoob Joseph
  2 siblings, 1 reply; 10+ messages in thread
From: Akhil Goyal @ 2019-11-20  5:58 UTC (permalink / raw)
  To: dev; +Cc: declan.doherty, anoobj, konstantin.ananyev, jerinj, Akhil Goyal

As per current support, Scatter Gather is only supported
for out of place input and output buffers.
This patch add support for Scatter Gather for inplace buffers.

Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
---
changes in v3:
- fixed hardcode in decryption path

changes in v2:
- fixed typo
- enabled corresponding test case
- removed hardcodings

 app/test/test_cryptodev_aes_test_vectors.h |  2 +
 doc/guides/cryptodevs/features/openssl.ini |  1 +
 drivers/crypto/openssl/rte_openssl_pmd.c   | 84 ++++++++++++++++------
 3 files changed, 66 insertions(+), 21 deletions(-)

diff --git a/app/test/test_cryptodev_aes_test_vectors.h b/app/test/test_cryptodev_aes_test_vectors.h
index 9afa3aef8..8307fcf9a 100644
--- a/app/test/test_cryptodev_aes_test_vectors.h
+++ b/app/test/test_cryptodev_aes_test_vectors.h
@@ -1773,6 +1773,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = {
 			    BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR |
 			    BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX |
 			    BLOCKCIPHER_TEST_TARGET_PMD_NITROX |
+			    BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
 			    BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX2
 	},
 	{
@@ -2248,6 +2249,7 @@ static const struct blockcipher_test_case aes_cipheronly_test_cases[] = {
 			BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC |
 			BLOCKCIPHER_TEST_TARGET_PMD_CAAM_JR |
 			BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX |
+			BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
 			BLOCKCIPHER_TEST_TARGET_PMD_OCTEONTX2
 	},
 	{
diff --git a/doc/guides/cryptodevs/features/openssl.ini b/doc/guides/cryptodevs/features/openssl.ini
index 6ddca39e7..30ffb111d 100644
--- a/doc/guides/cryptodevs/features/openssl.ini
+++ b/doc/guides/cryptodevs/features/openssl.ini
@@ -6,6 +6,7 @@
 [Features]
 Symmetric crypto       = Y
 Sym operation chaining = Y
+In Place SGL           = Y
 OOP SGL In LB  Out     = Y
 OOP LB  In LB  Out     = Y
 Asymmetric crypto      = Y
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c b/drivers/crypto/openssl/rte_openssl_pmd.c
index d68713e7e..91f028308 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -798,12 +798,12 @@ get_session(struct openssl_qp *qp, struct rte_crypto_op *op)
  */
 static inline int
 process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset,
-		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx)
+		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx, uint8_t inplace)
 {
 	struct rte_mbuf *m;
 	int dstlen;
 	int l, n = srclen;
-	uint8_t *src;
+	uint8_t *src, temp[EVP_CIPHER_CTX_block_size(ctx)];
 
 	for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
 			m = m->next)
@@ -813,6 +813,8 @@ process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset,
 		return -1;
 
 	src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
+	if (inplace)
+		*dst = src;
 
 	l = rte_pktmbuf_data_len(m) - offset;
 	if (srclen <= l) {
@@ -829,8 +831,24 @@ process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset,
 	n -= l;
 
 	for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
+		uint8_t diff = l - dstlen, rem;
+
 		src = rte_pktmbuf_mtod(m, uint8_t *);
-		l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
+		l = RTE_MIN(rte_pktmbuf_data_len(m), n);
+		if (diff && inplace) {
+			rem = RTE_MIN(l,
+				(EVP_CIPHER_CTX_block_size(ctx) - diff));
+			if (EVP_EncryptUpdate(ctx, temp,
+						&dstlen, src, rem) <= 0)
+				return -1;
+			n -= rem;
+			rte_memcpy(*dst, temp, diff);
+			rte_memcpy(src, temp + diff, rem);
+			src += rem;
+			l -= rem;
+		}
+		if (inplace)
+			*dst = src;
 		if (EVP_EncryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
 			return -1;
 		*dst += dstlen;
@@ -842,12 +860,12 @@ process_openssl_encryption_update(struct rte_mbuf *mbuf_src, int offset,
 
 static inline int
 process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset,
-		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx)
+		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx, uint8_t inplace)
 {
 	struct rte_mbuf *m;
 	int dstlen;
 	int l, n = srclen;
-	uint8_t *src;
+	uint8_t *src, temp[EVP_CIPHER_CTX_block_size(ctx)];
 
 	for (m = mbuf_src; m != NULL && offset > rte_pktmbuf_data_len(m);
 			m = m->next)
@@ -857,6 +875,8 @@ process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset,
 		return -1;
 
 	src = rte_pktmbuf_mtod_offset(m, uint8_t *, offset);
+	if (inplace)
+		*dst = src;
 
 	l = rte_pktmbuf_data_len(m) - offset;
 	if (srclen <= l) {
@@ -873,8 +893,24 @@ process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset,
 	n -= l;
 
 	for (m = m->next; (m != NULL) && (n > 0); m = m->next) {
+		uint8_t diff = l - dstlen, rem;
+
 		src = rte_pktmbuf_mtod(m, uint8_t *);
-		l = rte_pktmbuf_data_len(m) < n ? rte_pktmbuf_data_len(m) : n;
+		l = RTE_MIN(rte_pktmbuf_data_len(m), n);
+		if (diff && inplace) {
+			rem = RTE_MIN(l,
+				(EVP_CIPHER_CTX_block_size(ctx) - diff));
+			if (EVP_DecryptUpdate(ctx, temp,
+						&dstlen, src, rem) <= 0)
+				return -1;
+			n -= rem;
+			rte_memcpy(*dst, temp, diff);
+			rte_memcpy(src, temp + diff, rem);
+			src += rem;
+			l -= rem;
+		}
+		if (inplace)
+			*dst = src;
 		if (EVP_DecryptUpdate(ctx, *dst, &dstlen, src, l) <= 0)
 			return -1;
 		*dst += dstlen;
@@ -887,7 +923,8 @@ process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset,
 /** Process standard openssl cipher encryption */
 static int
 process_openssl_cipher_encrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
-		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx)
+		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx,
+		uint8_t inplace)
 {
 	int totlen;
 
@@ -897,7 +934,7 @@ process_openssl_cipher_encrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
 	EVP_CIPHER_CTX_set_padding(ctx, 0);
 
 	if (process_openssl_encryption_update(mbuf_src, offset, &dst,
-			srclen, ctx))
+			srclen, ctx, inplace))
 		goto process_cipher_encrypt_err;
 
 	if (EVP_EncryptFinal_ex(ctx, dst, &totlen) <= 0)
@@ -936,7 +973,8 @@ process_openssl_cipher_bpi_encrypt(uint8_t *src, uint8_t *dst,
 /** Process standard openssl cipher decryption */
 static int
 process_openssl_cipher_decrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
-		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx)
+		int offset, uint8_t *iv, int srclen, EVP_CIPHER_CTX *ctx,
+		uint8_t inplace)
 {
 	int totlen;
 
@@ -946,7 +984,7 @@ process_openssl_cipher_decrypt(struct rte_mbuf *mbuf_src, uint8_t *dst,
 	EVP_CIPHER_CTX_set_padding(ctx, 0);
 
 	if (process_openssl_decryption_update(mbuf_src, offset, &dst,
-			srclen, ctx))
+			srclen, ctx, inplace))
 		goto process_cipher_decrypt_err;
 
 	if (EVP_DecryptFinal_ex(ctx, dst, &totlen) <= 0)
@@ -1033,7 +1071,7 @@ process_openssl_auth_encryption_gcm(struct rte_mbuf *mbuf_src, int offset,
 
 	if (srclen > 0)
 		if (process_openssl_encryption_update(mbuf_src, offset, &dst,
-				srclen, ctx))
+				srclen, ctx, 0))
 			goto process_auth_encryption_gcm_err;
 
 	/* Workaround open ssl bug in version less then 1.0.1f */
@@ -1078,7 +1116,7 @@ process_openssl_auth_encryption_ccm(struct rte_mbuf *mbuf_src, int offset,
 
 	if (srclen > 0)
 		if (process_openssl_encryption_update(mbuf_src, offset, &dst,
-				srclen, ctx))
+				srclen, ctx, 0))
 			goto process_auth_encryption_ccm_err;
 
 	if (EVP_EncryptFinal_ex(ctx, dst, &len) <= 0)
@@ -1115,7 +1153,7 @@ process_openssl_auth_decryption_gcm(struct rte_mbuf *mbuf_src, int offset,
 
 	if (srclen > 0)
 		if (process_openssl_decryption_update(mbuf_src, offset, &dst,
-				srclen, ctx))
+				srclen, ctx, 0))
 			goto process_auth_decryption_gcm_err;
 
 	/* Workaround open ssl bug in version less then 1.0.1f */
@@ -1161,7 +1199,7 @@ process_openssl_auth_decryption_ccm(struct rte_mbuf *mbuf_src, int offset,
 
 	if (srclen > 0)
 		if (process_openssl_decryption_update(mbuf_src, offset, &dst,
-				srclen, ctx))
+				srclen, ctx, 0))
 			return -EFAULT;
 
 	return 0;
@@ -1376,13 +1414,16 @@ process_openssl_cipher_op
 {
 	uint8_t *dst, *iv;
 	int srclen, status;
+	uint8_t inplace = (mbuf_src == mbuf_dst) ? 1 : 0;
 	EVP_CIPHER_CTX *ctx_copy;
 
 	/*
-	 * Segmented destination buffer is not supported for
-	 * encryption/decryption
+	 * Segmented OOP destination buffer is not supported for encryption/
+	 * decryption. In case of des3ctr, even inplace segmented buffers are
+	 * not supported.
 	 */
-	if (!rte_pktmbuf_is_contiguous(mbuf_dst)) {
+	if (!rte_pktmbuf_is_contiguous(mbuf_dst) &&
+			(!inplace || sess->cipher.mode != OPENSSL_CIPHER_LIB)) {
 		op->status = RTE_CRYPTO_OP_STATUS_ERROR;
 		return;
 	}
@@ -1400,11 +1441,11 @@ process_openssl_cipher_op
 		if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
 			status = process_openssl_cipher_encrypt(mbuf_src, dst,
 					op->sym->cipher.data.offset, iv,
-					srclen, ctx_copy);
+					srclen, ctx_copy, inplace);
 		else
 			status = process_openssl_cipher_decrypt(mbuf_src, dst,
 					op->sym->cipher.data.offset, iv,
-					srclen, ctx_copy);
+					srclen, ctx_copy, inplace);
 	else
 		status = process_openssl_cipher_des3ctr(mbuf_src, dst,
 				op->sym->cipher.data.offset, iv,
@@ -1449,7 +1490,7 @@ process_openssl_docsis_bpi_op(struct rte_crypto_op *op,
 			/* Encrypt with the block aligned stream with CBC mode */
 			status = process_openssl_cipher_encrypt(mbuf_src, dst,
 					op->sym->cipher.data.offset, iv,
-					srclen, sess->cipher.ctx);
+					srclen, sess->cipher.ctx, 0);
 			if (last_block_len) {
 				/* Point at last block */
 				dst += srclen;
@@ -1499,7 +1540,7 @@ process_openssl_docsis_bpi_op(struct rte_crypto_op *op,
 			/* Decrypt with CBC mode */
 			status |= process_openssl_cipher_decrypt(mbuf_src, dst,
 					op->sym->cipher.data.offset, iv,
-					srclen, sess->cipher.ctx);
+					srclen, sess->cipher.ctx, 0);
 		}
 	}
 
@@ -2137,6 +2178,7 @@ cryptodev_openssl_create(const char *name,
 	dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
 			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
 			RTE_CRYPTODEV_FF_CPU_AESNI |
+			RTE_CRYPTODEV_FF_IN_PLACE_SGL |
 			RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT |
 			RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT |
 			RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO |
-- 
2.17.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dpdk-dev] [EXT] [PATCH v2] crypto/openssl: support SG for inplace buffers
  2019-11-20  4:31   ` [dpdk-dev] [EXT] " Anoob Joseph
@ 2019-11-20  6:11     ` Akhil Goyal
  0 siblings, 0 replies; 10+ messages in thread
From: Akhil Goyal @ 2019-11-20  6:11 UTC (permalink / raw)
  To: Anoob Joseph, dev
  Cc: declan.doherty, konstantin.ananyev, Jerin Jacob Kollanukkaran

> >  static inline int
> >  process_openssl_decryption_update(struct rte_mbuf *mbuf_src, int offset,
> > -		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx)
> > +		uint8_t **dst, int srclen, EVP_CIPHER_CTX *ctx, uint8_t inplace)
> >  {
> >  	struct rte_mbuf *m;
> >  	int dstlen;
> >  	int l, n = srclen;
> > -	uint8_t *src;
> > +	uint8_t *src, temp[128];
> 
> [Anoob] In case of encrypt_update, the buffer is
> 'temp[EVP_CIPHER_CTX_block_size(ctx)]'. Is the above intentional?
> 
Sending a v3 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dpdk-dev] [PATCH v3] crypto/openssl: support SG for inplace buffers
  2019-11-20  5:58   ` [dpdk-dev] [PATCH v3] " Akhil Goyal
@ 2019-11-20  6:23     ` Anoob Joseph
  2019-11-20 11:50       ` Akhil Goyal
  0 siblings, 1 reply; 10+ messages in thread
From: Anoob Joseph @ 2019-11-20  6:23 UTC (permalink / raw)
  To: Akhil Goyal, dev
  Cc: declan.doherty, konstantin.ananyev, Jerin Jacob Kollanukkaran

> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Akhil Goyal
> Sent: Wednesday, November 20, 2019 11:29 AM
> To: dev@dpdk.org
> Cc: declan.doherty@intel.com; Anoob Joseph <anoobj@marvell.com>;
> konstantin.ananyev@intel.com; Jerin Jacob Kollanukkaran
> <jerinj@marvell.com>; Akhil Goyal <akhil.goyal@nxp.com>
> Subject: [dpdk-dev] [PATCH v3] crypto/openssl: support SG for inplace buffers
> 
> As per current support, Scatter Gather is only supported for out of place input
> and output buffers.
> This patch add support for Scatter Gather for inplace buffers.
> 
> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>

Acked-by: Anoob Joseph <anoobj@marvell.com>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [dpdk-dev] [PATCH v3] crypto/openssl: support SG for inplace buffers
  2019-11-20  6:23     ` Anoob Joseph
@ 2019-11-20 11:50       ` Akhil Goyal
  0 siblings, 0 replies; 10+ messages in thread
From: Akhil Goyal @ 2019-11-20 11:50 UTC (permalink / raw)
  To: Anoob Joseph, dev
  Cc: declan.doherty, konstantin.ananyev, Jerin Jacob Kollanukkaran


> > As per current support, Scatter Gather is only supported for out of place input
> > and output buffers.
> > This patch add support for Scatter Gather for inplace buffers.
> >
> > Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
> 
> Acked-by: Anoob Joseph <anoobj@marvell.com>

Applied to dpdk-next-crypto



^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2019-11-20 11:50 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-02 12:42 [dpdk-dev] [PATCH] crypto/openssl: support SG for inplace buffers Akhil Goyal
2019-09-13  5:58 ` [dpdk-dev] [EXT] " Anoob Joseph
2019-09-19 15:57   ` Akhil Goyal
2019-11-18 13:36 ` [dpdk-dev] [PATCH v2] " Akhil Goyal
2019-11-19 14:19   ` Akhil Goyal
2019-11-20  4:31   ` [dpdk-dev] [EXT] " Anoob Joseph
2019-11-20  6:11     ` Akhil Goyal
2019-11-20  5:58   ` [dpdk-dev] [PATCH v3] " Akhil Goyal
2019-11-20  6:23     ` Anoob Joseph
2019-11-20 11:50       ` Akhil Goyal

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).