cryptodev: support multiple cipher data-units

Message ID 1615724283-26149-1-git-send-email-matan@nvidia.com (mailing list archive)
State Superseded, archived
Delegated to: akhil goyal
Headers
Series cryptodev: support multiple cipher data-units |

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/Intel-compilation success Compilation OK
ci/iol-abi-testing success Testing PASS
ci/iol-testing success Testing PASS
ci/iol-mellanox-Functional success Functional Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/intel-Testing success Testing PASS
ci/iol-mellanox-Performance success Performance Testing PASS

Commit Message

Matan Azrad March 14, 2021, 12:18 p.m. UTC
  In cryptography, a block cipher is a deterministic algorithm operating
on fixed-length groups of bits, called blocks.

A block cipher consists of two paired algorithms, one for encryption
and the other for decryption. Both algorithms accept two inputs:
an input block of size n bits and a key of size k bits; and both yield
an n-bit output block. The decryption algorithm is defined to be the
inverse function of the encryption.

For AES standard the block size is 16 bytes.
For AES in XTS mode, the data to be encrypted\decrypted does not have to
be multiple of 16B size, the unit of data is called data-unit.
The data-unit size can be any size in range [16B, 2^24B], so, in this
case, a data stream is divided into N amount of equal data-units and
must be encrypted\decrypted in the same data-unit resolution.

The current cryptodev API doesn't allow the user to select a specific
data-unit length supported by the devices.
In addition, there is no definition how the IV is detected per data-unit
when single operation includes more than one data-unit.

That causes applications to use single operation per data-unit even though
all the data is continuous in memory what reduces datapath performance.

Add a new feature flag to support multiple data-unit sizes, called
RTE_CRYPTODEV_FF_CIPHER_MULITPLE_DATA_UNITS.
Add a new field in cipher capability, called dataunit_set,
where the devices can report the range of the supported data-unit sizes.
Add a new cipher transformation field, called dataunit_len, where the user
can select the data-unit length for all the operations.

All the new fields do not change the size of their structures.

Using a bitmap to report the supported data-unit sizes capability allows
the devices to report a range simply as same as the user to read it
simply. also, thus sizes are usually common and probably will be shared
among different devices.

Signed-off-by: Matan Azrad <matan@nvidia.com>
---
 
First patch on it was sent as RFC.
This is first formal version, I updated according to comments on RFC discussions:
- Use data-unit term instead of block.
- Update cipher length description in OP.
- Improve descriptions on xform and capability.
- Improve commit log.

You welcome to comment more.
Please pay attention that a new fields was added in non-experimental structures but thier sizes hasn't changed.


 doc/guides/cryptodevs/features/default.ini |  1 +
 doc/guides/cryptodevs/overview.rst         |  3 +++
 doc/guides/rel_notes/release_21_05.rst     |  6 ++++++
 lib/librte_cryptodev/rte_crypto_sym.h      | 17 +++++++++++++++--
 lib/librte_cryptodev/rte_cryptodev.c       |  2 ++
 lib/librte_cryptodev/rte_cryptodev.h       | 18 ++++++++++++++++++
 6 files changed, 45 insertions(+), 2 deletions(-)
  

Comments

Akhil Goyal April 13, 2021, 12:02 p.m. UTC | #1
Hi Matan,

> In cryptography, a block cipher is a deterministic algorithm operating
> on fixed-length groups of bits, called blocks.
> 
> A block cipher consists of two paired algorithms, one for encryption
> and the other for decryption. Both algorithms accept two inputs:
> an input block of size n bits and a key of size k bits; and both yield
> an n-bit output block. The decryption algorithm is defined to be the
> inverse function of the encryption.
> 
> For AES standard the block size is 16 bytes.
> For AES in XTS mode, the data to be encrypted\decrypted does not have to
> be multiple of 16B size, the unit of data is called data-unit.
> The data-unit size can be any size in range [16B, 2^24B], so, in this
> case, a data stream is divided into N amount of equal data-units and
> must be encrypted\decrypted in the same data-unit resolution.
> 
> The current cryptodev API doesn't allow the user to select a specific
> data-unit length supported by the devices.
> In addition, there is no definition how the IV is detected per data-unit
> when single operation includes more than one data-unit.
> 
> That causes applications to use single operation per data-unit even though
> all the data is continuous in memory what reduces datapath performance.
> 
> Add a new feature flag to support multiple data-unit sizes, called
> RTE_CRYPTODEV_FF_CIPHER_MULITPLE_DATA_UNITS.
> Add a new field in cipher capability, called dataunit_set,
> where the devices can report the range of the supported data-unit sizes.
> Add a new cipher transformation field, called dataunit_len, where the user
> can select the data-unit length for all the operations.
> 
> All the new fields do not change the size of their structures.
> 
Please check that the CI is failing. I see that ignore exception is present in 
devtools/libabigail.abignore For rte_cryptodev. But not sure why this is still
failing. Can you check?

Regards,
Akhil

> Using a bitmap to report the supported data-unit sizes capability allows
> the devices to report a range simply as same as the user to read it
> simply. also, thus sizes are usually common and probably will be shared
> among different devices.
> 
> Signed-off-by: Matan Azrad <matan@nvidia.com>
> ---
  
Thomas Monjalon April 13, 2021, 4:39 p.m. UTC | #2
13/04/2021 14:02, Akhil Goyal:
> > All the new fields do not change the size of their structures.
> 
> Please check that the CI is failing. I see that ignore exception is present in 
> devtools/libabigail.abignore For rte_cryptodev. But not sure why this is still
> failing. Can you check?

There are 2 new fields:
	- rte_cryptodev_symmetric_capability.cipher.dataunit_set
	- rte_crypto_cipher_xform.dataunit_len

This is how the struct sizes are affected (before / after):

       struct       \      arch    |  32-bit |  64-bit |
-----------------------------------|---------|---------|
rte_cryptodev_symmetric_capability | 36 / 36 | 36 / 36 |
rte_crypto_cipher_xform            | 20 / 24 | 32 / 32 |

There is no change in rte_cryptodev_symmetric_capability because
the field is added in a light branch of the union.

The 64-bit size of rte_crypto_cipher_xform is unchanged (32)
because there were 4 padding bytes at the end (28 + 4).
But the 32-bit version has not such padding at the end,
so there is a breakage.

The only hole in 32-bit rte_crypto_cipher_xform is
2 bytes between key and iv.
Can we define dataunit_len as uint16_t?

The other side to check when playing with the ABI
is the default value of the holes for the new field.
The driver must work properly in case the application
did not explicitly set the new fields.
In general it means the compatible API should have memset(0).
In this case, it seems the new fields will be used only
in a new mlx5 driver, so it should be OK for now.
But usage of the new fields in an existing driver must
be checked carefully during the compatibility period.
  

Patch

diff --git a/doc/guides/cryptodevs/features/default.ini b/doc/guides/cryptodevs/features/default.ini
index 17b177f..978bb30 100644
--- a/doc/guides/cryptodevs/features/default.ini
+++ b/doc/guides/cryptodevs/features/default.ini
@@ -31,6 +31,7 @@  CPU crypto             =
 Symmetric sessionless  =
 Non-Byte aligned data  =
 Sym raw data path API  =
+Cipher multiple data units =
 
 ;
 ; Supported crypto algorithms of a default crypto driver.
diff --git a/doc/guides/cryptodevs/overview.rst b/doc/guides/cryptodevs/overview.rst
index e2a1e08..0597d25 100644
--- a/doc/guides/cryptodevs/overview.rst
+++ b/doc/guides/cryptodevs/overview.rst
@@ -46,6 +46,9 @@  Supported Feature Flags
    - "Digest encrypted" feature flag means PMD support hash-cipher cases,
      where generated digest is appended to and encrypted with the data.
 
+   - "CIPHER_MULITPLE_DATA_UNITS" feature flag means PMD support operations
+      on multiple data-units message.
+
 
 Supported Cipher Algorithms
 ---------------------------
diff --git a/doc/guides/rel_notes/release_21_05.rst b/doc/guides/rel_notes/release_21_05.rst
index 88e7607..e4e41df 100644
--- a/doc/guides/rel_notes/release_21_05.rst
+++ b/doc/guides/rel_notes/release_21_05.rst
@@ -91,6 +91,12 @@  New Features
   * Added a command line option to configure forced speed for Ethernet port.
     ``dpdk-testpmd -c 0xff  -- -i  --eth-link-speed N``
 
+* **Added feature to support multiple data-units on cryptodev library API.**
+
+  The Cryptodev library has been enhanced to allow operations on multiple
+  data-units for AES-XTS algorithm, the data-unit length should be set in the
+  transformation. A capability for it was added too.
+
 
 Removed Items
 -------------
diff --git a/lib/librte_cryptodev/rte_crypto_sym.h b/lib/librte_cryptodev/rte_crypto_sym.h
index 9d572ec..6a07666 100644
--- a/lib/librte_cryptodev/rte_crypto_sym.h
+++ b/lib/librte_cryptodev/rte_crypto_sym.h
@@ -265,6 +265,18 @@  struct rte_crypto_cipher_xform {
 		 * which can be in the range 7 to 13 inclusive.
 		 */
 	} iv;	/**< Initialisation vector parameters */
+
+	uint32_t dataunit_len;
+	/**< When RTE_CRYPTODEV_FF_CIPHER_MULITPLE_DATA_UNITS is enabled,
+	 * this is the data-unit length of the algorithm, otherwise or when the
+	 * value is 0, use the operation length.
+	 * The value should be in the range defined by the dataunit_set field
+	 * in the cipher capability.
+	 *
+	 * - For AES-XTS it is the size of data-unit, from IEEE Std 1619-2007.
+	 * For-each data-unit in the operation, the tweak(IV) value is
+	 * assigned consecutively starting from the operation assigned IV.
+	 */
 };
 
 /** Symmetric Authentication / Hash Algorithms
@@ -701,9 +713,10 @@  struct rte_crypto_sym_op {
 					 /**< The message length, in bytes, of the
 					  * source buffer on which the cryptographic
 					  * operation will be computed.
+					  * This is also the same as the result length.
 					  * This must be a multiple of the block size
-					  * if a block cipher is being used. This is
-					  * also the same as the result length.
+					  * or a multiple of data-unit length as
+					  * described in xform.
 					  *
 					  * @note
 					  * For SNOW 3G @ RTE_CRYPTO_AUTH_SNOW3G_UEA2,
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 40f55a3..51f8448 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -617,6 +617,8 @@  struct rte_cryptodev_sym_session_pool_private_data {
 		return "SYM_SESSIONLESS";
 	case RTE_CRYPTODEV_FF_NON_BYTE_ALIGNED_DATA:
 		return "NON_BYTE_ALIGNED_DATA";
+	case RTE_CRYPTODEV_FF_CIPHER_MULITPLE_DATA_UNITS:
+		return "CIPHER_MULITPLE_DATA_UNITS";
 	default:
 		return NULL;
 	}
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index ae34f33..cd914ff 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -96,6 +96,17 @@  struct rte_crypto_param_range {
 };
 
 /**
+ * Data-unit lengths of cipher algorithms, each bit represents single or
+ * range of data-unit lengths
+ */
+#define RTE_CRYPTO_CIPHER_DATA_UNIT_LEN_512_BYTES	(1 << 0)
+#define RTE_CRYPTO_CIPHER_DATA_UNIT_LEN_520_BYTES	(1 << 1)
+#define RTE_CRYPTO_CIPHER_DATA_UNIT_LEN_4048_BYTES	(1 << 2)
+#define RTE_CRYPTO_CIPHER_DATA_UNIT_LEN_4096_BYTES	(1 << 3)
+#define RTE_CRYPTO_CIPHER_DATA_UNIT_LEN_4160_BYTES	(1 << 4)
+#define RTE_CRYPTO_CIPHER_DATA_UNIT_LEN_1M_BYTES	(1 << 5)
+
+/**
  * Symmetric Crypto Capability
  */
 struct rte_cryptodev_symmetric_capability {
@@ -127,6 +138,11 @@  struct rte_cryptodev_symmetric_capability {
 			/**< cipher key size range */
 			struct rte_crypto_param_range iv_size;
 			/**< Initialisation vector data size range */
+			uint32_t dataunit_set;
+			/**<
+			 * A bitmap for a set of the supported data-unit lengths
+			 * 0 for any defined length in the algorithm standard
+			 */
 		} cipher;
 		/**< Symmetric Cipher transform capabilities */
 		struct {
@@ -461,6 +477,8 @@  struct rte_cryptodev_asym_capability_idx {
 /**< Support operations on data which is not byte aligned */
 #define RTE_CRYPTODEV_FF_SYM_RAW_DP			(1ULL << 24)
 /**< Support accelerator specific symmetric raw data-path APIs */
+#define RTE_CRYPTODEV_FF_CIPHER_MULITPLE_DATA_UNITS	(1ULL << 25)
+/**< Support operations on multiple data-units data */
 
 /**
  * Get the name of a crypto device feature flag