Skip to contentSkip to conversation

A proposed DPDK Crypto API and device framework

PATCH In review Declan Doherty 2 participants 8 messages Aug 20, 2015 – Sep 15, 2015

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover A proposed DPDK Crypto API and device framework

This series of patches proposes a set of application burst oriented APIs for asynchronous symmetric cryptographic functions within DPDK. It also contains a poll mode driver cryptographic device framework for the implementation of crypto devices within DPDK.

In the patch set we also have included 2 reference implementations of crypto PMDs, both are still early in development but act as an example of how we envisage the APIs and device framework to be used. Currently both implementations only support AES128-CBC with HMAC_SHA1/SHA256/SHA512 authentication operations. The first device is a purely software PMD based on Intel's multi-buffer library, which utilises both AES-NI instructions and vector operations to accelerate crypto operations and the second PMD utilises Intel's Quick Assist Technology (on DH895xxC) to provide hardware accelerated crypto operations.

The proposed API set supports two functional modes of operation:

1, A session oriented mode. In this mode the user creates a crypto session which defines all the immutable data required to perform a particular crypto operation in advance, including cipher/hash algorithms and operations to be performed as well as the keys to used etc. The session is then referenced by the crypto operation data structure which is a data structure specific to each mbuf. It is used to contain all mutable data about the cryto operation to be performed, such as data offsets and lengths into the mbuf's data payload for cipher and hash operations to be performed.

2, A session-less mode. In this mode the user is able to provision crypto operations on an mbuf without the need to have a cached session created in advance, but at the cost of entailing the overhead of calculating authentication pre-computes and preforming key expansions in-line with the crypto operation. Only the crypto operation data structure must be completed in this mode but all of immutable crypto operation parameters that would be normally set within a session are now specified within the crypto operation data structure. Once all mutable and immutable parameters are set the crypto operation data structure can be attached to the specified mbuf and enqueued on a specified crypto device for processing.

The patch set contains the following features:
- Crypto device APIs and device framework
- Example implementation of a software crypto PMD based on multi-buffer library
- Example implementation of a hardware crypto PMD baed on Intel QAT(DH895xxC)
- Unit and performance test's which give and example of utilising the crypto API's.

Current Status: The patch set has only been compiled and tested with 64-bit gcc. There is no support for chained mbuf's and as mentioned above the PMD's have only currently implemented support for AES128-CBC/AES256-CBC/AES512-CBC and HMAC_SHA1/SHA256/SHA512. At this stage we are looking for feedback on the proposed API's and the framework implementations.

Declan Doherty (3):
cryptodev: Initial DPDK Crypto APIs and device framework release
aesni_mb_pmd: Initial implementation of multi buffer based crypto
device
app/test: add cryptodev unit and performance tests

John Griffin (1):
qat_crypto_pmd: Addition of a new QAT DPDK PMD.

 app/test/Makefile                                  |    7 +-
 app/test/test.c                                    |   91 +-
 app/test/test.h                                    |   34 +-
 app/test/test_cryptodev.c                          | 1079 +++++++++++++++
 app/test/test_cryptodev_perf.c                     | 1438 ++++++++++++++++++++
 app/test/test_link_bonding.c                       |    6 +-
 app/test/test_link_bonding_mode4.c                 |    7 +-
 config/common_bsdapp                               |   30 +-
 config/common_linuxapp                             |   29 +-
 doc/api/doxy-api-index.md                          |    1 +
 doc/api/doxy-api.conf                              |    1 +
 doc/guides/cryptodevs/aesni_mb.rst                 |   76 ++
 doc/guides/cryptodevs/index.rst                    |   43 +
 doc/guides/cryptodevs/qat.rst                      |  155 +++
 doc/guides/index.rst                               |    1 +
 drivers/Makefile                                   |    1 +
 drivers/crypto/Makefile                            |   38 +
 drivers/crypto/aesni_mb/Makefile                   |   67 +
 drivers/crypto/aesni_mb/aesni_mb_ops.h             |  206 +++
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c         |  550 ++++++++
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c     |  346 +++++
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h |  224 +++
 drivers/crypto/aesni_mb/rte_pmd_aesni_version.map  |    5 +
 drivers/crypto/qat/Makefile                        |   63 +
 .../qat/qat_adf/adf_transport_access_macros.h      |  173 +++
 drivers/crypto/qat/qat_adf/icp_qat_fw.h            |  316 +++++
 drivers/crypto/qat/qat_adf/icp_qat_fw_la.h         |  404 ++++++
 drivers/crypto/qat/qat_adf/icp_qat_hw.h            |  305 +++++
 drivers/crypto/qat/qat_adf/qat_algs.h              |  124 ++
 drivers/crypto/qat/qat_adf/qat_algs_build_desc.c   |  462 +++++++
 drivers/crypto/qat/qat_crypto.c                    |  469 +++++++
 drivers/crypto/qat/qat_crypto.h                    |   99 ++
 drivers/crypto/qat/qat_logs.h                      |   78 ++
 drivers/crypto/qat/qat_qp.c                        |  372 +++++
 drivers/crypto/qat/rte_pmd_qat_version.map         |    5 +
 drivers/crypto/qat/rte_qat_cryptodev.c             |  128 ++
 lib/Makefile                                       |    1 +
 lib/librte_cryptodev/Makefile                      |   60 +
 lib/librte_cryptodev/rte_crypto.h                  |  649 +++++++++
 lib/librte_cryptodev/rte_crypto_version.map        |   40 +
 lib/librte_cryptodev/rte_cryptodev.c               |  966 +++++++++++++
 lib/librte_cryptodev/rte_cryptodev.h               |  550 ++++++++
 lib/librte_cryptodev/rte_cryptodev_pmd.h           |  622 +++++++++
 lib/librte_eal/common/include/rte_log.h            |    1 +
 lib/librte_eal/common/include/rte_memory.h         |   14 +-
 lib/librte_mbuf/rte_mbuf.c                         |    1 +
 lib/librte_mbuf/rte_mbuf.h                         |   51 +
 mk/rte.app.mk                                      |    8 +
 48 files changed, 10346 insertions(+), 50 deletions(-)
 create mode 100644 app/test/test_cryptodev.c
 create mode 100644 app/test/test_cryptodev_perf.c
 create mode 100644 doc/guides/cryptodevs/aesni_mb.rst
 create mode 100644 doc/guides/cryptodevs/index.rst
 create mode 100644 doc/guides/cryptodevs/qat.rst
 create mode 100644 drivers/crypto/Makefile
 create mode 100644 drivers/crypto/aesni_mb/Makefile
 create mode 100644 drivers/crypto/aesni_mb/aesni_mb_ops.h
 create mode 100644 drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
 create mode 100644 drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
 create mode 100644 drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
 create mode 100644 drivers/crypto/aesni_mb/rte_pmd_aesni_version.map
 create mode 100644 drivers/crypto/qat/Makefile
 create mode 100644 drivers/crypto/qat/qat_adf/adf_transport_access_macros.h
 create mode 100644 drivers/crypto/qat/qat_adf/icp_qat_fw.h
 create mode 100644 drivers/crypto/qat/qat_adf/icp_qat_fw_la.h
 create mode 100644 drivers/crypto/qat/qat_adf/icp_qat_hw.h
 create mode 100644 drivers/crypto/qat/qat_adf/qat_algs.h
 create mode 100644 drivers/crypto/qat/qat_adf/qat_algs_build_desc.c
 create mode 100644 drivers/crypto/qat/qat_crypto.c
 create mode 100644 drivers/crypto/qat/qat_crypto.h
 create mode 100644 drivers/crypto/qat/qat_logs.h
 create mode 100644 drivers/crypto/qat/qat_qp.c
 create mode 100644 drivers/crypto/qat/rte_pmd_qat_version.map
 create mode 100644 drivers/crypto/qat/rte_qat_cryptodev.c
 create mode 100644 lib/librte_cryptodev/Makefile
 create mode 100644 lib/librte_cryptodev/rte_crypto.h
 create mode 100644 lib/librte_cryptodev/rte_crypto_version.map
 create mode 100644 lib/librte_cryptodev/rte_cryptodev.c
 create mode 100644 lib/librte_cryptodev/rte_cryptodev.h
 create mode 100644 lib/librte_cryptodev/rte_cryptodev_pmd.h
Signature · 1 line
1.9.3
#1 lore raw

PATCH 1/4 cryptodev: Initial DPDK Crypto APIs and device framework release

This patch contains the initial proposed APIs and device framework for integrating crypto packet processing into DPDK.

features include:
- Crypto device configuration / management APIs
- Definitions of supported cipher algorithms and operations.
- Definitions of supported hash/authentication algorithms and operations.
- Crypto session management APIs
- Crypto operation data structures and APIs allocation of crypto operation structure used to specify the crypto operations to be performed on a particular mbuf.
- Extension of mbuf to contain crypto operation data pointer and extra flags.
- Burst enqueue / dequeue APIs for processing of crypto operations.

---
 config/common_bsdapp                        |   9 +-
 config/common_linuxapp                      |   7 +
 doc/api/doxy-api-index.md                   |   1 +
 doc/api/doxy-api.conf                       |   1 +
 lib/Makefile                                |   1 +
 lib/librte_cryptodev/Makefile               |  60 ++
 lib/librte_cryptodev/rte_crypto.h           | 649 +++++++++++++++++++
 lib/librte_cryptodev/rte_crypto_version.map |  40 ++
 lib/librte_cryptodev/rte_cryptodev.c        | 966 ++++++++++++++++++++++++++++
 lib/librte_cryptodev/rte_cryptodev.h        | 550 ++++++++++++++++
 lib/librte_cryptodev/rte_cryptodev_pmd.h    | 622 ++++++++++++++++++
 lib/librte_eal/common/include/rte_log.h     |   1 +
 lib/librte_eal/common/include/rte_memory.h  |  14 +-
 lib/librte_mbuf/rte_mbuf.c                  |   1 +
 lib/librte_mbuf/rte_mbuf.h                  |  51 ++
 mk/rte.app.mk                               |   1 +
 16 files changed, 2971 insertions(+), 3 deletions(-)
 create mode 100644 lib/librte_cryptodev/Makefile
 create mode 100644 lib/librte_cryptodev/rte_crypto.h
 create mode 100644 lib/librte_cryptodev/rte_crypto_version.map
 create mode 100644 lib/librte_cryptodev/rte_cryptodev.c
 create mode 100644 lib/librte_cryptodev/rte_cryptodev.h
 create mode 100644 lib/librte_cryptodev/rte_cryptodev_pmd.h
config/common_bsdapp +8 -1
index b37dcf4..ed30180 100644
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -147,6 +147,13 @@ CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS=16
 CONFIG_RTE_ETHDEV_RXTX_CALLBACKS=y
 
 #
+# Compile generic Crypto device library
+#
+CONFIG_RTE_LIBRTE_CRYPTODEV=y
+CONFIG_RTE_LIBRTE_CRYPTODEV_DEBUG=y
+CONFIG_RTE_MAX_CRYPTOPORTS=32
+
+#
 # Support NIC bypass logic
 #
 CONFIG_RTE_NIC_BYPASS=n
config/common_linuxapp +7 -0
index 0de43d5..12a75c6 100644
@@ -145,6 +145,13 @@ CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS=16
 CONFIG_RTE_ETHDEV_RXTX_CALLBACKS=y
 
 #
+# Compile generic Crypto device library
+#
+CONFIG_RTE_LIBRTE_CRYPTODEV=y
+CONFIG_RTE_LIBRTE_CRYPTODEV_DEBUG=y
+CONFIG_RTE_MAX_CRYPTODEVS=64
+
+#
 # Support NIC bypass logic
 #
 CONFIG_RTE_NIC_BYPASS=n
doc/api/doxy-api-index.md +1 -0
index 72ac3c4..bdb6130 100644
@@ -39,6 +39,7 @@ There are many libraries, so their headers may be grouped by topics:
   [dev]                (@ref rte_dev.h),
   [ethdev]             (@ref rte_ethdev.h),
   [ethctrl]            (@ref rte_eth_ctrl.h),
+  [cryptodev]          (@ref rte_cryptodev.h),
   [devargs]            (@ref rte_devargs.h),
   [bond]               (@ref rte_eth_bond.h),
   [vhost]              (@ref rte_virtio_net.h),
doc/api/doxy-api.conf +1 -0
index cfb4627..7244b8f 100644
@@ -37,6 +37,7 @@ INPUT                   = doc/api/doxy-api-index.md \
                           lib/librte_cfgfile \
                           lib/librte_cmdline \
                           lib/librte_compat \
+                          lib/librte_cryptodev \
                           lib/librte_distributor \
                           lib/librte_ether \
                           lib/librte_hash \
lib/Makefile +1 -0
index 2055539..9e5f484 100644
@@ -41,6 +41,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += librte_timer
 DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
 DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline
 DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
+DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += librte_cryptodev
 DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += librte_vhost
 DIRS-$(CONFIG_RTE_LIBRTE_HASH) += librte_hash
 DIRS-$(CONFIG_RTE_LIBRTE_LPM) += librte_lpm
lib/librte_cryptodev/Makefile new file +60 -0

60 lines not on this page · raw message

lib/librte_cryptodev/rte_crypto.h new file +649 -0

649 lines not on this page · raw message

lib/librte_cryptodev/rte_crypto_version.map new file +40 -0
new file mode 100644
index 0000000..c93fcad
@@ -0,0 +1,40 @@
+DPDK_2.2 {
+	global:
+
+	rte_cryptodev_create_vdev;
+	rte_cryptodev_get_dev_id;
+	rte_cryptodev_count;
+	rte_cryptodev_configure;
+	rte_cryptodev_start;
+	rte_cryptodev_stop;
+	rte_cryptodev_close;
+	rte_cryptodev_queue_pair_setup;
+	rte_cryptodev_queue_pair_start;
+	rte_cryptodev_queue_pair_stop;
+	rte_cryptodev_queue_pair_count;
+	rte_cryptodev_stats_get;
+	rte_cryptodev_stats_reset;
+	rte_cryptodev_info_get;
+	rte_cryptodev_callback_register;
+	rte_cryptodev_callback_unregister;
+	rte_cryptodev_enqueue_burst;
+	rte_cryptodev_dequeue_burst;
+	rte_cryptodev_create_crypto_op;
+	rte_cryptodev_crypto_op_free;
+	rte_cryptodev_session_create;
+	rte_cryptodev_session_free;
+
+	rte_cryptodev_pmd_get_dev;
+	rte_cryptodev_pmd_get_named_dev;
+	rte_cryptodev_pmd_is_valid_dev;
+	rte_cryptodev_pmd_allocate;
+	rte_cryptodev_pmd_virtual_dev_init;
+	rte_cryptodev_pmd_release_device;
+	rte_cryptodev_pmd_attach;
+	rte_cryptodev_pmd_detach;
+	rte_cryptodev_pmd_driver_register;
+	rte_cryptodev_pmd_socket_id;
+	rte_cryptodev_pmd_callback_process;
+
+	local: *;
+};
lib/librte_cryptodev/rte_cryptodev.c new file +966 -0

966 lines not on this page · raw message

lib/librte_cryptodev/rte_cryptodev.h new file +550 -0

550 lines not on this page · raw message

lib/librte_cryptodev/rte_cryptodev_pmd.h new file +622 -0

622 lines not on this page · raw message

lib/librte_eal/common/include/rte_log.h +1 -0
index ede0dca..2e47e7f 100644
@@ -78,6 +78,7 @@ extern struct rte_logs rte_logs;
 #define RTE_LOGTYPE_TABLE   0x00004000 /**< Log related to table. */
 #define RTE_LOGTYPE_PIPELINE 0x00008000 /**< Log related to pipeline. */
 #define RTE_LOGTYPE_MBUF    0x00010000 /**< Log related to mbuf. */
+#define RTE_LOGTYPE_CRYPTODEV 0x00020000 /**< Log related to cryptodev. */
 
 /* these log types can be used in an application */
 #define RTE_LOGTYPE_USER1   0x01000000 /**< User-defined log type 1. */
lib/librte_eal/common/include/rte_memory.h +12 -2
index 1bed415..c8e1d8a 100644
@@ -76,9 +76,19 @@ enum rte_page_sizes {
 /**< Return the first cache-aligned value greater or equal to size. */
 
 /**
+ * Force alignment.
+ */
+#define __rte_align(a) __attribute__((__aligned__(a)))
+
+/**
  * Force alignment to cache line.
  */
-#define __rte_cache_aligned __attribute__((__aligned__(RTE_CACHE_LINE_SIZE)))
+#define __rte_cache_aligned __rte_align(RTE_CACHE_LINE_SIZE)
+
+/**
+ * Force a structure to be packed
+ */
+#define __rte_packed __attribute__((__packed__))
 
 typedef uint64_t phys_addr_t; /**< Physical address definition. */
 #define RTE_BAD_PHYS_ADDR ((phys_addr_t)-1)
@@ -104,7 +114,7 @@ struct rte_memseg {
 	 /**< store segment MFNs */
 	uint64_t mfn[DOM0_NUM_MEMBLOCK];
 #endif
-} __attribute__((__packed__));
+} __rte_packed;
 
 /**
  * Lock page in physical memory and prevent from swapping.
lib/librte_mbuf/rte_mbuf.c +1 -0
index e416312..a8e9dbc 100644
@@ -281,6 +281,7 @@ const char *rte_get_rx_ol_flag_name(uint64_t mask)
 const char *rte_get_tx_ol_flag_name(uint64_t mask)
 {
 	switch (mask) {
+	case PKT_TX_CRYPTO_OP: return "PKT_TX_CRYPTO_OP";
 	case PKT_TX_VLAN_PKT: return "PKT_TX_VLAN_PKT";
 	case PKT_TX_IP_CKSUM: return "PKT_TX_IP_CKSUM";
 	case PKT_TX_TCP_CKSUM: return "PKT_TX_TCP_CKSUM";
lib/librte_mbuf/rte_mbuf.h +51 -0

17 lines not on this page · raw message

mk/rte.app.mk +1 -0
index 3871205..c7ee033 100644

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Signature · 1 line
1.9.3

Part of the diff is not shown here. View the raw message.

#2 lore raw

Re: [PATCH 1/4] cryptodev: Initial DPDK Crypto APIs and device framework release

Quoted 20 lines · Declan Doherty

This patch contains the initial proposed APIs and device framework for integrating crypto packet processing into DPDK.

features include:
- Crypto device configuration / management APIs
- Definitions of supported cipher algorithms and operations.
- Definitions of supported hash/authentication algorithms and operations.
- Crypto session management APIs
- Crypto operation data structures and APIs allocation of crypto operation structure used to specify the crypto operations to be performed on a particular mbuf.
- Extension of mbuf to contain crypto operation data pointer and extra flags.
- Burst enqueue / dequeue APIs for processing of crypto operations.

Quoted 1 line

Hey, only had a qick read so some of this might be off base, but a few comments in line

Quoted 88 lines

<snip>
index 0000000..b776609

lib/librte_cryptodev/rte_crypto.h new file +83 -0
@@ -0,0 +1,649 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2015 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_CRYPTO_H_
+#define _RTE_CRYPTO_H_
+
+/**
+ * @file rte_crypto.h
+ *
+ * RTE Cryptographic Definitions
+ *
+ * Defines symmetric cipher and authentication algorithms and modes, as well
+ * as supported symmetric crypto operation combinations.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_mbuf.h>
+#include <rte_memory.h>
+#include <rte_mempool.h>
+
+/**
+ * This enumeration lists different types of crypto operations supported by rte
+ * crypto devices. The operation type is defined during session registration and
+ * cannot be changed for a session once it has been setup, or if using a
+ * session-less crypto operation it is defined within the crypto operation
+ * op_params.
+ */
+enum rte_crypto_operation_chain {
+	RTE_CRYPTO_SYM_OP_CIPHER_ONLY,
+	/**< Cipher only operation on the data */
+	RTE_CRYPTO_SYM_OP_HASH_ONLY,
+	/**< Hash only operation on the data */
+	RTE_CRYPTO_SYM_OPCHAIN_HASH_CIPHER,
+	/**<
+	 * Chain a hash followed by any cipher operation.
+	 *
+	 * If it is required that the result of the hash (i.e. the digest)
+	 * is going to be included in the data to be ciphered, then:
+	 *
+	 * - The digest MUST be placed in the destination buffer at the
+	 *   location corresponding to the end of the data region to be hashed
+	 *   (hash_start_offset + message length to hash),  i.e. there must be
+	 *   no gaps between the start of the digest and the end of the data
+	 *   region to be hashed.
+	 *
+	 * - The message length to cipher member of the rte_crypto_op_data
+	 *   structure must be equal to the overall length of the plain text,
+	 *   the digest length and any (optional) trailing data that is to be
+	 *   included.
+	 *
+	 * - The message length to cipher must be a multiple to the block

lib/librte_cryptodev/rte_crypto.h line 93

Quoted 10 lines
lib/librte_cryptodev/rte_crypto.h new file +10 -0
+	 *   size if a block cipher is being used - the implementation does not
+	 *   pad.
+	 */
+	RTE_CRYPTO_SYM_OPCHAIN_CIPHER_HASH,
+	/**<
+	 * Chain any cipher followed by any hash operation.The hash operation
+	 * will be performed on the ciphertext resulting from the cipher
+	 * operation.
+	 */
+};

So, this seems a bit...not sure what the word is..specific perhaps? For an API. That is to say, if a underlying device supports performing multiple operations in a single transaction, I'm not sure that should be exposed in this way. As the number of devices and chain combinations grow, so too will this list, and if there are multiple simmilar (but distinct) chain operations, an application will have to know which chains are applicable to which devices which is sub-optimal

Instead, perhaps it would be better to simply ennumerate the list of crypto primitives that a device supports (HASH/CIPHER/etc), and allow the application to define the desired chain when creating a session. That is to say, an appilcation can create a session that requests a given chain of operations (using an array of the primitive enum perhaps). The implementing PMD is then responsible for implementing that chain in hardware or software if need be. If you need to report on the disposition of the implementation, you can do so via return code (i.e. SESSION_OK_HW_IMPL or SESSION_OK_SW_IMPL).

Using this method, more complex operations can be implemented with chain macros (e.g. AEAD is just an array of primitives [CIPHER, HASH])

Quoted 100 lines

<snip>

lib/librte_cryptodev/rte_cryptodev.c new file +93 -0
new file mode 100644
index 0000000..a1797ce
@@ -0,0 +1,966 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2015 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <netinet/in.h>
+
+#include <rte_byteorder.h>
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_dev.h>
+#include <rte_interrupts.h>
+#include <rte_pci.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_memzone.h>
+#include <rte_launch.h>
+#include <rte_tailq.h>
+#include <rte_eal.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_common.h>
+#include <rte_ring.h>
+#include <rte_mempool.h>
+#include <rte_malloc.h>
+#include <rte_mbuf.h>
+#include <rte_errno.h>
+#include <rte_spinlock.h>
+#include <rte_string_fns.h>
+
+#include "rte_crypto.h"
+#include "rte_cryptodev.h"
+
+
+
+/* Macros to check for invalid function pointers in dev_ops structure */
+#define FUNC_PTR_OR_ERR_RET(func, retval) do { \
+	if ((func) == NULL) { \
+		CDEV_LOG_ERR("Function not supported"); \
+		return retval; \
+	} \
+} while (0)
+
+#define PROC_PRIMARY_OR_RET() do { \
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY) { \
+		CDEV_LOG_ERR("Cannot run in secondary processes"); \
+		return; \
+	} \
+} while (0)
+
+#define PROC_PRIMARY_OR_ERR_RET(retval) do { \
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY) { \
+		CDEV_LOG_ERR("Cannot run in secondary processes"); \
+		return retval; \

lib/librte_cryptodev/rte_cryptodev.c line 103

Quoted 10 lines
lib/librte_cryptodev/rte_cryptodev.c new file +10 -0
+	} \
+} while (0)
+
+#define FUNC_PTR_OR_RET(func) do { \
+	if ((func) == NULL) { \
+		CDEV_LOG_ERR("Function not supported"); \
+		return; \
+	} \
+} while (0)
+

These are all defined in rte_ethdev. You should just move those to a public place rather then re-creating them

Quoted 250 lines
lib/librte_cryptodev/rte_cryptodev.c new file +250 -0
+struct rte_cryptodev rte_crypto_devices[RTE_MAX_CRYPTODEVS];
+
+static struct rte_cryptodev_global cryptodev_globals = {
+		.devs			= &rte_crypto_devices[0],
+		.data			= NULL,
+		.nb_devs		= 0,
+		.max_devs		= RTE_MAX_CRYPTODEVS
+};
+
+struct rte_cryptodev_global *rte_cryptodev_globals = &cryptodev_globals;
+
+/* spinlock for crypto device callbacks */
+static rte_spinlock_t rte_cryptodev_cb_lock = RTE_SPINLOCK_INITIALIZER;
+
+
+/**
+ * The user application callback description.
+ *
+ * It contains callback address to be registered by user application,
+ * the pointer to the parameters for callback, and the event type.
+ */
+struct rte_cryptodev_callback {
+	TAILQ_ENTRY(rte_cryptodev_callback) next; /**< Callbacks list */
+	rte_cryptodev_cb_fn cb_fn;                /**< Callback address */
+	void *cb_arg;                           /**< Parameter for callback */
+	enum rte_cryptodev_event_type event;          /**< Interrupt event type */
+	uint32_t active;                        /**< Callback is executing */
+};
+
+int
+rte_cryptodev_create_vdev(const char *name, const char *args)
+{
+	return rte_eal_vdev_init(name, args);
+}
+
+
+static inline void
+rte_cryptodev_data_alloc(int socket_id)
+{
+	const unsigned flags = 0;
+	const struct rte_memzone *mz;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		mz = rte_memzone_reserve("rte_cryptodev_data",
+				cryptodev_globals.max_devs * sizeof(struct rte_cryptodev_data),
+				socket_id, flags);
+	} else
+		mz = rte_memzone_lookup("rte_cryptodev_data");
+	if (mz == NULL)
+		rte_panic("Cannot allocate memzone for the crypto device data");
+
+	cryptodev_globals.data = mz->addr;
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		memset(cryptodev_globals.data, 0,
+				cryptodev_globals.max_devs * sizeof(struct rte_cryptodev_data));
+}
+
+
+static uint8_t
+rte_cryptodev_find_free_device_index(void)
+{
+	uint8_t dev_id;
+
+	for (dev_id = 0; dev_id < RTE_MAX_CRYPTODEVS; dev_id++) {
+		if (rte_crypto_devices[dev_id].attached == RTE_CRYPTODEV_DETACHED)
+			return dev_id;
+	}
+	return RTE_MAX_CRYPTODEVS;
+}
+
+struct rte_cryptodev *
+rte_cryptodev_pmd_allocate(const char *name, enum pmd_type type, int socket_id)
+{
+	uint8_t dev_id;
+	struct rte_cryptodev *cryptodev;
+
+	dev_id = rte_cryptodev_find_free_device_index();
+	if (dev_id == RTE_MAX_CRYPTODEVS) {
+		CDEV_LOG_ERR("Reached maximum number of crypto devices");
+		return NULL;
+	}
+
+	if (cryptodev_globals.data == NULL)
+		rte_cryptodev_data_alloc(socket_id);
+
+	if (rte_cryptodev_pmd_get_named_dev(name) != NULL) {
+		CDEV_LOG_ERR("Crypto device with name %s already "
+				"allocated!", name);
+		return NULL;
+	}
+
+	cryptodev = rte_cryptodev_pmd_get_dev(dev_id);
+	cryptodev->data = &cryptodev_globals.data[dev_id];
+	snprintf(cryptodev->data->name, RTE_CRYPTODEV_NAME_MAX_LEN, "%s", name);
+	cryptodev->data->dev_id = dev_id;
+	cryptodev->attached = RTE_CRYPTODEV_ATTACHED;
+	cryptodev->pmd_type = type;
+	cryptodev_globals.nb_devs++;
+
+	return cryptodev;
+}
+
+static inline int
+rte_cryptodev_create_unique_device_name(char *name, size_t size,
+		struct rte_pci_device *pci_dev)
+{
+	int ret;
+
+	if ((name == NULL) || (pci_dev == NULL))
+		return -EINVAL;
+
+	ret = snprintf(name, size, "%d:%d.%d",
+			pci_dev->addr.bus, pci_dev->addr.devid,
+			pci_dev->addr.function);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+int
+rte_cryptodev_pmd_release_device(struct rte_cryptodev *cryptodev)
+{
+	if (cryptodev == NULL)
+		return -EINVAL;
+
+	cryptodev->attached = RTE_CRYPTODEV_DETACHED;
+	cryptodev_globals.nb_devs--;
+	return 0;
+}
+
+struct rte_cryptodev *
+rte_cryptodev_pmd_virtual_dev_init(const char *name, size_t dev_private_size,
+		int socket_id)
+{
+	struct rte_cryptodev *cryptodev;
+
+	/* allocate device structure */
+	cryptodev = rte_cryptodev_pmd_allocate(name, PMD_VDEV, socket_id);
+	if (cryptodev == NULL)
+		return NULL;
+
+	/* allocate private device structure */
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		cryptodev->data->dev_private =
+				rte_zmalloc("%s private structure",
+						dev_private_size,
+						RTE_CACHE_LINE_SIZE);
+
+		if (cryptodev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private device"
+					" data");
+	}
+
+	/* initialise user call-back tail queue */
+	TAILQ_INIT(&(cryptodev->link_intr_cbs));
+
+	return cryptodev;
+}
+
+static int
+rte_cryptodev_init(struct rte_pci_driver *pci_drv,
+		struct rte_pci_device *pci_dev)
+{
+	struct rte_cryptodev_driver *cryptodrv;
+	struct rte_cryptodev *cryptodev;
+
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+
+	int retval;
+
+	cryptodrv = (struct rte_cryptodev_driver *)pci_drv;
+	if (cryptodrv == NULL)
+			return -ENODEV;
+
+	/* Create unique Crypto device name using PCI address */
+	rte_cryptodev_create_unique_device_name(cryptodev_name,
+			sizeof(cryptodev_name), pci_dev);
+
+	cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name, PMD_PDEV, rte_socket_id());
+	if (cryptodev == NULL)
+		return -ENOMEM;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		cryptodev->data->dev_private =
+				rte_zmalloc_socket("cryptodev private structure",
+						cryptodrv->dev_private_size,
+						RTE_CACHE_LINE_SIZE, rte_socket_id());
+
+		if (cryptodev->data->dev_private == NULL)
+			rte_panic("Cannot allocate memzone for private device data");
+	}
+
+	cryptodev->pci_dev = pci_dev;
+	cryptodev->driver = cryptodrv;
+
+	/* init user callbacks */
+	TAILQ_INIT(&(cryptodev->link_intr_cbs));
+
+	/* Invoke PMD device initialization function */
+	retval = (*cryptodrv->cryptodev_init)(cryptodrv, cryptodev);
+	if (retval == 0)
+		return 0;
+
+	CDEV_LOG_ERR("driver %s: crypto_dev_init(vendor_id=0x%u device_id=0x%x)"
+			" failed", pci_drv->name,
+			(unsigned) pci_dev->id.vendor_id,
+			(unsigned) pci_dev->id.device_id);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	cryptodev->attached = RTE_CRYPTODEV_DETACHED;
+	cryptodev_globals.nb_devs--;
+
+	return -ENXIO;
+}
+
+static int
+rte_cryptodev_uninit(struct rte_pci_device *pci_dev)
+{
+	const struct rte_cryptodev_driver *cryptodrv;
+	struct rte_cryptodev *cryptodev;
+	char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+	int ret;
+
+	if (pci_dev == NULL)
+		return -EINVAL;
+
+	/* Create unique device name using PCI address */
+	rte_cryptodev_create_unique_device_name(cryptodev_name,
+			sizeof(cryptodev_name), pci_dev);
+
+	cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
+	if (cryptodev == NULL)
+		return -ENODEV;
+
+	cryptodrv = (const struct rte_cryptodev_driver *)pci_dev->driver;
+	if (cryptodrv == NULL)
+			return -ENODEV;
+
+	/* Invoke PMD device uninit function */
+	if (*cryptodrv->cryptodev_uninit) {
+		ret = (*cryptodrv->cryptodev_uninit)(cryptodrv, cryptodev);
+		if (ret)
+			return ret;
+	}
+
+	/* free ether device */
+	rte_cryptodev_pmd_release_device(cryptodev);
+

lib/librte_cryptodev/rte_cryptodev.c line 363

Quoted 10 lines
lib/librte_cryptodev/rte_cryptodev.c new file +10 -0
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		rte_free(cryptodev->data->dev_private);
+
+	cryptodev->pci_dev = NULL;
+	cryptodev->driver = NULL;
+	cryptodev->data = NULL;
+
+	return 0;
+}
+

Shouldn't there be some interlock here if a device is being removed to block on closure of all the sessions that may be open against it, and serializtion againsnt any list modifications for tracking of these devices?

Quoted 154 lines
lib/librte_cryptodev/rte_cryptodev.c new file +154 -0
+int
+rte_cryptodev_pmd_driver_register(struct rte_cryptodev_driver *cryptodrv,
+		enum pmd_type type)
+{
+	/* Call crypto device initialization directly if device is virtual */
+	if (type == PMD_VDEV)
+		return rte_cryptodev_init((struct rte_pci_driver *)cryptodrv,
+				NULL);
+
+	/* Register PCI driver for physical device intialisation during
+	 * PCI probing */
+	cryptodrv->pci_drv.devinit = rte_cryptodev_init;
+	cryptodrv->pci_drv.devuninit = rte_cryptodev_uninit;
+	rte_eal_pci_register(&cryptodrv->pci_drv);
+	return 0;
+}
+
+int
+rte_cryptodev_pmd_attach(const char *devargs __rte_unused,
+			uint8_t *dev_id __rte_unused)
+{
+	RTE_LOG(ERR, EAL, "Hotplug support isn't enabled");
+	return -1;
+}
+
+/* detach the device, then store the name of the device */
+int
+rte_cryptodev_pmd_detach(uint8_t dev_id __rte_unused,
+			char *name __rte_unused)
+{
+	RTE_LOG(ERR, EAL, "Hotplug support isn't enabled");
+	return -1;
+}
+
+uint16_t
+rte_cryptodev_queue_pair_count(uint8_t dev_id)
+{
+	struct rte_cryptodev *dev;
+
+	dev = &rte_crypto_devices[dev_id];
+	return dev->data->nb_queue_pairs;
+}
+
+static int
+rte_cryptodev_queue_pairs_config(struct rte_cryptodev *dev, uint16_t nb_qpairs, int socket_id)
+{
+	struct rte_cryptodev_info dev_info;
+	uint16_t old_nb_queues = dev->data->nb_queue_pairs;
+	void **qp;
+	unsigned i;
+
+	if ((dev == NULL) || (nb_qpairs < 1)) {
+		CDEV_LOG_ERR("invalid param: dev %p, nb_queues %u",
+							dev, nb_qpairs);
+		return -EINVAL;
+	}
+
+	CDEV_LOG_DEBUG("Setup %d queues pairs on device %u",
+			nb_qpairs, dev->data->dev_id);
+
+
+	memset(&dev_info, 0, sizeof(struct rte_cryptodev_info));
+
+	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
+	(*dev->dev_ops->dev_infos_get)(dev, &dev_info);
+
+	if (nb_qpairs > (dev_info.max_queue_pairs)) {
+		CDEV_LOG_ERR("Invalid num queue_pairs (%u) for dev %u",
+				nb_qpairs, dev->data->dev_id);
+	    return (-EINVAL);
+	}
+
+	if (dev->data->queue_pairs == NULL) { /* first time configuration */
+		dev->data->queue_pairs = rte_zmalloc_socket(
+				"cryptodev->queue_pairs",
+				sizeof(dev->data->queue_pairs[0]) * nb_qpairs,
+				RTE_CACHE_LINE_SIZE, socket_id);
+
+		if (dev->data->queue_pairs == NULL) {
+			dev->data->nb_queue_pairs = 0;
+			CDEV_LOG_ERR("failed to get memory for qp meta data, "
+							"nb_queues %u", nb_qpairs);
+			return -(ENOMEM);
+		}
+	} else { /* re-configure */
+		FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_release, -ENOTSUP);
+
+		qp = dev->data->queue_pairs;
+
+		for (i = nb_qpairs; i < old_nb_queues; i++)
+			(*dev->dev_ops->queue_pair_release)(dev, i);
+		qp = rte_realloc(qp, sizeof(qp[0]) * nb_qpairs,
+				RTE_CACHE_LINE_SIZE);
+		if (qp == NULL) {
+			CDEV_LOG_ERR("failed to realloc qp meta data,"
+						" nb_queues %u", nb_qpairs);
+			return -(ENOMEM);
+		}
+		if (nb_qpairs > old_nb_queues) {
+			uint16_t new_qs = nb_qpairs - old_nb_queues;
+
+			memset(qp + old_nb_queues, 0,
+				sizeof(qp[0]) * new_qs);
+		}
+
+		dev->data->queue_pairs = qp;
+
+	}
+	dev->data->nb_queue_pairs = nb_qpairs;
+	return 0;
+}
+
+int
+rte_cryptodev_queue_pair_start(uint8_t dev_id, uint16_t queue_pair_id)
+{
+	struct rte_cryptodev *dev;
+
+	/* This function is only safe when called from the primary process
+	 * in a multi-process setup*/
+	PROC_PRIMARY_OR_ERR_RET(-E_RTE_SECONDARY);
+
+	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
+		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
+		return -EINVAL;
+	}
+
+	dev = &rte_crypto_devices[dev_id];
+	if (queue_pair_id >= dev->data->nb_queue_pairs) {
+		CDEV_LOG_ERR("Invalid queue_pair_id=%d", queue_pair_id);
+		return -EINVAL;
+	}
+
+	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_start, -ENOTSUP);
+
+	return dev->dev_ops->queue_pair_start(dev, queue_pair_id);
+
+}
+
+int
+rte_cryptodev_queue_pair_stop(uint8_t dev_id, uint16_t queue_pair_id)
+{
+	struct rte_cryptodev *dev;
+
+	/* This function is only safe when called from the primary process
+	 * in a multi-process setup*/
+	PROC_PRIMARY_OR_ERR_RET(-E_RTE_SECONDARY);
+
+	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
+		CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
+		return -EINVAL;
+	}
+
+	dev = &rte_crypto_devices[dev_id];
+	if (queue_pair_id >= dev->data->nb_queue_pairs) {

lib/librte_cryptodev/rte_cryptodev.c line 527

Quoted 10 lines
lib/librte_cryptodev/rte_cryptodev.c new file +10 -0
+		CDEV_LOG_ERR("Invalid queue_pair_id=%d", queue_pair_id);
+		return -EINVAL;
+	}
+
+	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_stop, -ENOTSUP);
+
+	return dev->dev_ops->queue_pair_stop(dev, queue_pair_id);
+
+}
+

So, I'm a bit confused here. How do you communicate with a cryptodev. I see you're creating queue pairs here, which I think are intended for input/output, but you also allow the creation of sessions. The former seems to have no linkage to the latter, so you have sessionless queue pairs and sessions without method to perform operations on? I'm clearly missing something, but I can't see the relationship.

#3 lore raw

Re: [PATCH 1/4] cryptodev: Initial DPDK Crypto APIs and device framework release

Quoted 21 lines · Neil Horman
Quoted 20 lines · Declan Doherty

This patch contains the initial proposed APIs and device framework for integrating crypto packet processing into DPDK.

features include:
- Crypto device configuration / management APIs
- Definitions of supported cipher algorithms and operations.
- Definitions of supported hash/authentication algorithms and operations.
- Crypto session management APIs
- Crypto operation data structures and APIs allocation of crypto operation structure used to specify the crypto operations to be performed on a particular mbuf.
- Extension of mbuf to contain crypto operation data pointer and extra flags.
- Burst enqueue / dequeue APIs for processing of crypto operations.

Quoted 5 lines
Quoted 1 line

Hey, only had a qick read so some of this might be off base, but a few comments in line

Hey Neil, thanks for the feedback, I've reply in line below.

Quoted 18 lines
Quoted 1 line

<snip>

So, this seems a bit...not sure what the word is..specific perhaps? For an API. That is to say, if a underlying device supports performing multiple operations in a single transaction, I'm not sure that should be exposed in this way. As the number of devices and chain combinations grow, so too will this list, and if there are multiple simmilar (but distinct) chain operations, an application will have to know which chains are applicable to which devices which is sub-optimal

Instead, perhaps it would be better to simply ennumerate the list of crypto primitives that a device supports (HASH/CIPHER/etc), and allow the application to define the desired chain when creating a session. That is to say, an appilcation can create a session that requests a given chain of operations (using an array of the primitive enum perhaps). The implementing PMD is then responsible for implementing that chain in hardware or software if need be. If you need to report on the disposition of the implementation, you can do so via return code (i.e. SESSION_OK_HW_IMPL or SESSION_OK_SW_IMPL).

Quoted 3 lines

Using this method, more complex operations can be implemented with chain macros (e.g. AEAD is just an array of primitives [CIPHER, HASH])

ok, we may have let the hardware which we have available to us bias the scope of the API a little. I guess something similar to the approach taken by the OCF in BSD may be appropriate. This has a more generic structure for specifying any type of crypto operations and a next pointer to the next operations in the chain, this would make the provisioning of operations and there chaining much more generic? I'll put together a prototype and come back to the mailing list with it for further comment.

Quoted 4 lines
Quoted 1 line

<snip>

These are all defined in rte_ethdev. You should just move those to a public place rather then re-creating them

Will do.

Quoted 5 lines
Quoted 1 line

<snip>

Shouldn't there be some interlock here if a device is being removed to block on closure of all the sessions that may be open against it, and serializtion againsnt any list modifications for tracking of these devices?

Good point, I hadn't considered the releasing of session resources on
device closure. I'll also look further at the device management, at this point we just had the minimal infrastructure in place to allow functional testing.

Quoted 8 lines
Quoted 1 line

<snip>

So, I'm a bit confused here. How do you communicate with a cryptodev. I see you're creating queue pairs here, which I think are intended for input/output, but you also allow the creation of sessions. The former seems to have no linkage to the latter, so you have sessionless queue pairs and sessions without method to perform operations on? I'm clearly missing something, but I can't see the relationship.

All data path communication with the cryptodev is done via the burst enqueue and dequeue functions, see the rte_cryptodev.h .

So the session structure is a container for all the immutable data used to perform a crypto operation on a particular packet flow. We have a crypto operation data struct which contains the mutable data such as data offsets and lengths, initialization vectorsand the location of the digest, and additional data etc.

The crypto operation can be session based or session-less. If session based, it will have a pointer to a valid session for use with a specific cryptodev otherwise all the immutable crypto operation data parameters need to be set in the crypto operation data struct which is attached to each mbuf which will be enqueued with the cryptodev for processing.

Once the crypto operation data struct is completed, it is attached
to the specific mbuf which contains the data to be operated on. The cryptodev can then handle a burst of mbuf's for processing enqueued on it using the burst_enqueue function.

The data associations from the mbuf, crypto_op and crypto_session are connected as below:

mbuf
|-> data_payload etc..
--> crypto_op

         |-> crypto session
         |-> digest data ptr / length
         |-> iv data ptr / length
         --> data offsets

One of the main reason for using session is that there are some
computationally costly precomputes which are required for authentication algos and key expansions for the cipher algos. By using a crypto session you can do these calculation once outside of the data-path and then the session can be used for every packet in a flow which requires that particular crypto transformation.

The one drawback to this is that if you are dealing with a system that has tens of thousands or millions of flows, then you end up caching a huge amount of data in the crypto session which is more than likely also stored in the application layer above.

The cryptodev can then handle burst of mbuf's for processing passed into it using the burst_enqueue function. The rte_cryptodev_burst_enqueue is analogous to an rte_eth_dev_tx_burst, but we use the enqueue/dequeue naming convention as tx/rx don't really what sense in the case of a crypto device where the input and output queues are intrinsically linked.

Cheers
Declan

#4 lore raw

PATCH 1/1 cryptodev: changes to crypto operation APIs to support non prescriptive chaining of crypto transforms in a crypto operation. app/test: updates to cryptodev unit tests to support new xform chaining APIs. aesni_mb_pmd: updates to device to support API changes

In reply to Neil Horman

Proposed changes to cryptodev API for comment based on Neil's comments on the initial RFC. I have included the updates to the cryptodev unit test suite and the AESNI multi buffer PMD for illustrative purposes, I will include the changes for the QAT in a V1 patchset if the proposes changes to the API are acceptable.

---
 app/test/test_cryptodev.c                          | 276 +++++++++++++++------
 drivers/crypto/aesni_mb/aesni_mb_ops.h             |   2 +-
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c         | 188 +++++++++-----
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c     |  10 +-
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h |  28 ++-
 lib/librte_cryptodev/rte_crypto.h                  | 141 ++++++++---
 lib/librte_cryptodev/rte_cryptodev.c               |  54 ++--
 lib/librte_cryptodev/rte_cryptodev.h               |  26 +-
 lib/librte_cryptodev/rte_cryptodev_pmd.h           |  10 +-
 9 files changed, 506 insertions(+), 229 deletions(-)
app/test/test_cryptodev.c +206 -70
index 68cc0bf..93b7e0a 100644
@@ -62,6 +62,8 @@
 #define DIGEST_BYTE_LENGTH_SHA1		(BYTE_LENGTH(160))
 #define DIGEST_BYTE_LENGTH_SHA256	(BYTE_LENGTH(256))
 #define DIGEST_BYTE_LENGTH_SHA512	(BYTE_LENGTH(512))
+#define DIGEST_BYTE_LENGTH_AES_XCBC     (BYTE_LENGTH(96))
+#define AES_XCBC_MAC_KEY_SZ             (16)
 
 #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA1		(12)
 #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA256		(16)
@@ -75,13 +77,13 @@ struct crypto_testsuite_params {
 	struct rte_cryptodev_config conf;
 	struct rte_cryptodev_qp_conf qp_conf;
 
-	uint8_t valid_devs[RTE_MAX_CRYPTODEVS];
+	uint8_t valid_devs[RTE_CRYPTO_MAX_DEVS];
 	uint8_t valid_dev_count;
 };
 
 struct crypto_unittest_params {
-	struct rte_crypto_cipher_params cipher_params;
-	struct rte_crypto_hash_params hash_params;
+	struct rte_crypto_xform cipher_xform;
+	struct rte_crypto_xform auth_xform;
 
 	struct rte_cryptodev_session *sess;
 
@@ -92,6 +94,17 @@ struct crypto_unittest_params {
 	uint8_t *digest;
 };
 
+/*
+ * Forward declarations.
+ */
+static int
+test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(struct crypto_unittest_params *ut_params);
+
+static int
+test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_session *sess,
+		struct crypto_unittest_params *ut_params,
+		struct crypto_testsuite_params *ts_param);
+
 static struct rte_mbuf *
 setup_test_string(struct rte_mempool *mpool,
 		const char *string, size_t len, uint8_t blocksize)
@@ -184,7 +197,7 @@ testsuite_setup(void)
 	}
 
 	ts_params->crypto_op_pool = rte_crypto_op_pool_create("CRYPTO_OP_POOL",
-			NUM_MBUFS, MBUF_CACHE_SIZE, rte_socket_id());
+			NUM_MBUFS, MBUF_CACHE_SIZE, 2, rte_socket_id());
 	if (ts_params->crypto_op_pool == NULL) {
 		RTE_LOG(ERR, USER1, "Can't create CRYPTO_OP_POOL\n");
 		return TEST_FAILED;
@@ -436,6 +449,11 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_ciphertext[] = {
 	0X95, 0XBB, 0X26, 0X74, 0X69, 0X12, 0X7F, 0XF1, 0XBB, 0XFF, 0XAE, 0XB5, 0X99, 0X6E, 0XCB, 0X0C
 };
 
+static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest[] = {
+	0x9a, 0X4f, 0X88, 0X1b, 0Xb6, 0X8f, 0Xd8, 0X60,
+	0X42, 0X1a, 0X7d, 0X3d, 0Xf5, 0X82, 0X80, 0Xf1,
+	0X18, 0X8c, 0X1d, 0X32 };
+
 
 static int
 test_AES_CBC_HMAC_SHA1_encrypt_digest(void)
@@ -452,22 +470,28 @@ test_AES_CBC_HMAC_SHA1_encrypt_digest(void)
 	TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest");
 
 	/* Setup Cipher Parameters */
-	ut_params->cipher_params.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC;
-	ut_params->cipher_params.op = RTE_CRYPTO_SYM_CIPHER_OP_ENCRYPT;
-	ut_params->cipher_params.key.data = aes_cbc_key;
-	ut_params->cipher_params.key.length = CIPHER_KEY_LENGTH_AES_CBC;
+	ut_params->cipher_xform.type = RTE_CRYPTO_XFORM_CIPHER;
+	ut_params->cipher_xform.next = &ut_params->auth_xform;
+
+	ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC;
+	ut_params->cipher_xform.cipher.op = RTE_CRYPTO_SYM_CIPHER_OP_ENCRYPT;
+	ut_params->cipher_xform.cipher.key.data = aes_cbc_key;
+	ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC;
 
 	/* Setup HMAC Parameters */
-	ut_params->hash_params.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_GENERATE;
-	ut_params->hash_params.algo = RTE_CRYPTO_SYM_HASH_SHA1_HMAC;
-	ut_params->hash_params.auth_key.length = HMAC_KEY_LENGTH_SHA1;
-	ut_params->hash_params.auth_key.data = hmac_sha1_key;
-	ut_params->hash_params.digest_length = DIGEST_BYTE_LENGTH_SHA1;
+
+	ut_params->auth_xform.type = RTE_CRYPTO_XFORM_AUTH;
+	ut_params->auth_xform.next = NULL;
+
+	ut_params->auth_xform.auth.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_GENERATE;
+	ut_params->auth_xform.auth.algo = RTE_CRYPTO_SYM_HASH_SHA1_HMAC;
+	ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA1;
+	ut_params->auth_xform.auth.key.data = hmac_sha1_key;
+	ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA1;
 
 	/* Create Crypto session*/
 	ut_params->sess = rte_cryptodev_session_create(ts_params->valid_devs[0],
-			&ut_params->cipher_params, &ut_params->hash_params,
-			RTE_CRYPTO_SYM_OPCHAIN_CIPHER_HASH);
+			&ut_params->cipher_xform);
 	TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
 
 	/* Generate Crypto op data structure */
@@ -522,6 +546,88 @@ test_AES_CBC_HMAC_SHA1_encrypt_digest(void)
 	return TEST_SUCCESS;
 }
 
+
+static int
+test_AES_CBC_HMAC_SHA1_encrypt_digest_sessionless(void)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	struct crypto_unittest_params *ut_params = &unittest_params;
+
+	/* Generate test mbuf data and space for digest */
+	ut_params->ibuf = setup_test_string(ts_params->mbuf_pool, catch_22_quote,
+			QUOTE_512_BYTES, 0);
+
+	ut_params->digest = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
+			DIGEST_BYTE_LENGTH_SHA1);
+	TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest");
+
+	/* Generate Crypto op data structure */
+	ut_params->op = rte_crypto_op_alloc_sessionless(ts_params->crypto_op_pool, 2);
+	TEST_ASSERT_NOT_NULL(ut_params->op, "Failed to allocate crypto_op");
+
+	/* Set crypto operation data parameters */
+	ut_params->op->xform->type = RTE_CRYPTO_XFORM_CIPHER;
+
+	/* cipher parameters */
+	ut_params->op->xform->cipher.op = RTE_CRYPTO_SYM_CIPHER_OP_ENCRYPT;
+	ut_params->op->xform->cipher.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC;
+	ut_params->op->xform->cipher.key.data = aes_cbc_key;
+	ut_params->op->xform->cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC;
+
+	/* hash parameters */
+	ut_params->op->xform->next->type = RTE_CRYPTO_XFORM_AUTH;
+
+	ut_params->op->xform->next->auth.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_GENERATE;
+	ut_params->op->xform->next->auth.algo = RTE_CRYPTO_SYM_HASH_SHA1_HMAC;
+	ut_params->op->xform->next->auth.key.length = HMAC_KEY_LENGTH_SHA1;
+	ut_params->op->xform->next->auth.key.data = hmac_sha1_key;
+	ut_params->op->xform->next->auth.digest_length = DIGEST_BYTE_LENGTH_SHA1;
+
+	ut_params->op->digest.data = ut_params->digest;
+	ut_params->op->digest.phys_addr = rte_pktmbuf_mtophys_offset(ut_params->ibuf,
+			QUOTE_512_BYTES);
+	ut_params->op->digest.length = DIGEST_BYTE_LENGTH_SHA1;
+
+	ut_params->op->iv.data = (uint8_t *)rte_pktmbuf_prepend(ut_params->ibuf,
+			CIPHER_IV_LENGTH_AES_CBC);
+	ut_params->op->iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf);
+	ut_params->op->iv.length = CIPHER_IV_LENGTH_AES_CBC;
+
+	rte_memcpy(ut_params->op->iv.data, aes_cbc_iv, CIPHER_IV_LENGTH_AES_CBC);
+
+	ut_params->op->data.to_cipher.offset = CIPHER_IV_LENGTH_AES_CBC;
+	ut_params->op->data.to_cipher.length = QUOTE_512_BYTES;
+	ut_params->op->data.to_hash.offset = CIPHER_IV_LENGTH_AES_CBC;
+	ut_params->op->data.to_hash.length = QUOTE_512_BYTES;
+
+	rte_pktmbuf_attach_crypto_op(ut_params->ibuf, ut_params->op);
+
+	/* Process crypto operation */
+	ut_params->obuf = process_crypto_request(ts_params->valid_devs[0],
+			ut_params->ibuf);
+	TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf");
+
+	/* Validate obuf */
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+			rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) +
+			CIPHER_IV_LENGTH_AES_CBC,
+			catch_22_quote_2_512_bytes_AES_CBC_ciphertext,
+			QUOTE_512_BYTES,
+			"Ciphertext data not as expected");
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+			rte_pktmbuf_mtod(ut_params->obuf, uint8_t *) +
+			CIPHER_IV_LENGTH_AES_CBC + QUOTE_512_BYTES,
+			catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest,
+			gbl_cryptodev_type == RTE_CRYPTODEV_AESNI_MB_PMD ?
+					TRUNCATED_DIGEST_BYTE_LENGTH_SHA1 :
+					DIGEST_BYTE_LENGTH_SHA1,
+			"Generated digest data not as expected");
+
+	free_testsuite_mbufs();
+	return TEST_SUCCESS;
+}
+
 static int
 test_AES_CBC_HMAC_SHA1_decrypt_digest_verify(void)
 {
@@ -542,22 +648,27 @@ test_AES_CBC_HMAC_SHA1_decrypt_digest_verify(void)
 			DIGEST_BYTE_LENGTH_SHA1);
 
 	/* Setup Cipher Parameters */
-	ut_params->cipher_params.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC;
-	ut_params->cipher_params.op = RTE_CRYPTO_SYM_CIPHER_OP_DECRYPT;
-	ut_params->cipher_params.key.data = aes_cbc_key;
-	ut_params->cipher_params.key.length = CIPHER_KEY_LENGTH_AES_CBC;
+	ut_params->cipher_xform.type = RTE_CRYPTO_XFORM_CIPHER;
+	ut_params->cipher_xform.next = NULL;
+
+	ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC;
+	ut_params->cipher_xform.cipher.op = RTE_CRYPTO_SYM_CIPHER_OP_DECRYPT;
+	ut_params->cipher_xform.cipher.key.data = aes_cbc_key;
+	ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC;
 
 	/* Setup HMAC Parameters */
-	ut_params->hash_params.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_VERIFY;
-	ut_params->hash_params.algo = RTE_CRYPTO_SYM_HASH_SHA1_HMAC;
-	ut_params->hash_params.auth_key.length = HMAC_KEY_LENGTH_SHA1;
-	ut_params->hash_params.auth_key.data = hmac_sha1_key;
-	ut_params->hash_params.digest_length = DIGEST_BYTE_LENGTH_SHA1;
+	ut_params->auth_xform.type = RTE_CRYPTO_XFORM_AUTH;
+	ut_params->auth_xform.next = &ut_params->cipher_xform;
+
+	ut_params->auth_xform.auth.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_VERIFY;
+	ut_params->auth_xform.auth.algo = RTE_CRYPTO_SYM_HASH_SHA1_HMAC;
+	ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA1;
+	ut_params->auth_xform.auth.key.data = hmac_sha1_key;
+	ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA1;
 
 	/* Create Crypto session*/
 	ut_params->sess = rte_cryptodev_session_create(ts_params->valid_devs[0],
-			&ut_params->cipher_params, &ut_params->hash_params,
-			RTE_CRYPTO_SYM_OPCHAIN_HASH_CIPHER);
+			&ut_params->auth_xform);
 	TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
 
 	/* Generate Crypto op data structure */
@@ -641,22 +752,27 @@ test_AES_CBC_HMAC_SHA256_encrypt_digest(void)
 	TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest");
 
 	/* Setup Cipher Parameters */
-	ut_params->cipher_params.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC;
-	ut_params->cipher_params.op = RTE_CRYPTO_SYM_CIPHER_OP_ENCRYPT;
-	ut_params->cipher_params.key.data = aes_cbc_key;
-	ut_params->cipher_params.key.length = CIPHER_KEY_LENGTH_AES_CBC;
+	ut_params->cipher_xform.type = RTE_CRYPTO_XFORM_CIPHER;
+	ut_params->cipher_xform.next = &ut_params->auth_xform;
+
+	ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC;
+	ut_params->cipher_xform.cipher.op = RTE_CRYPTO_SYM_CIPHER_OP_ENCRYPT;
+	ut_params->cipher_xform.cipher.key.data = aes_cbc_key;
+	ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC;
 
 	/* Setup HMAC Parameters */
-	ut_params->hash_params.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_GENERATE;
-	ut_params->hash_params.algo = RTE_CRYPTO_SYM_HASH_SHA256_HMAC;
-	ut_params->hash_params.auth_key.length = HMAC_KEY_LENGTH_SHA256;
-	ut_params->hash_params.auth_key.data = hmac_sha256_key;
-	ut_params->hash_params.digest_length = DIGEST_BYTE_LENGTH_SHA256;
+	ut_params->auth_xform.type = RTE_CRYPTO_XFORM_AUTH;
+	ut_params->auth_xform.next = NULL;
+
+	ut_params->auth_xform.auth.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_GENERATE;
+	ut_params->auth_xform.auth.algo = RTE_CRYPTO_SYM_HASH_SHA256_HMAC;
+	ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA256;
+	ut_params->auth_xform.auth.key.data = hmac_sha256_key;
+	ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA256;
 
 	/* Create Crypto session*/
 	ut_params->sess = rte_cryptodev_session_create(ts_params->valid_devs[0],
-			&ut_params->cipher_params, &ut_params->hash_params,
-			RTE_CRYPTO_SYM_OPCHAIN_CIPHER_HASH);
+			&ut_params->cipher_xform);
 	TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
 
 	/* Generate Crypto op data structure */
@@ -731,22 +847,27 @@ test_AES_CBC_HMAC_SHA256_decrypt_digest_verify(void)
 			DIGEST_BYTE_LENGTH_SHA256);
 
 	/* Setup Cipher Parameters */
-	ut_params->cipher_params.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC;
-	ut_params->cipher_params.op = RTE_CRYPTO_SYM_CIPHER_OP_DECRYPT;
-	ut_params->cipher_params.key.data = aes_cbc_key;
-	ut_params->cipher_params.key.length = CIPHER_KEY_LENGTH_AES_CBC;
+	ut_params->cipher_xform.type = RTE_CRYPTO_XFORM_CIPHER;
+	ut_params->cipher_xform.next = NULL;
+
+	ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC;
+	ut_params->cipher_xform.cipher.op = RTE_CRYPTO_SYM_CIPHER_OP_DECRYPT;
+	ut_params->cipher_xform.cipher.key.data = aes_cbc_key;
+	ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC;
 
 	/* Setup HMAC Parameters */
-	ut_params->hash_params.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_VERIFY;
-	ut_params->hash_params.algo = RTE_CRYPTO_SYM_HASH_SHA256_HMAC;
-	ut_params->hash_params.auth_key.data = hmac_sha256_key;
-	ut_params->hash_params.auth_key.length = HMAC_KEY_LENGTH_SHA256;
-	ut_params->hash_params.digest_length = DIGEST_BYTE_LENGTH_SHA256;
+	ut_params->auth_xform.type = RTE_CRYPTO_XFORM_AUTH;
+	ut_params->auth_xform.next = &ut_params->cipher_xform;
+
+	ut_params->auth_xform.auth.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_VERIFY;
+	ut_params->auth_xform.auth.algo = RTE_CRYPTO_SYM_HASH_SHA256_HMAC;
+	ut_params->auth_xform.auth.key.data = hmac_sha256_key;
+	ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA256;
+	ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA256;
 
 	/* Create Crypto session*/
 	ut_params->sess = rte_cryptodev_session_create(ts_params->valid_devs[0],
-			&ut_params->cipher_params, &ut_params->hash_params,
-			RTE_CRYPTO_SYM_OPCHAIN_HASH_CIPHER);
+			&ut_params->auth_xform);
 	TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
 
 	/* Generate Crypto op data structure */
@@ -837,22 +958,27 @@ test_AES_CBC_HMAC_SHA512_encrypt_digest(void)
 	TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest");
 
 	/* Setup Cipher Parameters */
-	ut_params->cipher_params.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC;
-	ut_params->cipher_params.op = RTE_CRYPTO_SYM_CIPHER_OP_ENCRYPT;
-	ut_params->cipher_params.key.data = aes_cbc_key;
-	ut_params->cipher_params.key.length = CIPHER_KEY_LENGTH_AES_CBC;
+	ut_params->cipher_xform.type = RTE_CRYPTO_XFORM_CIPHER;
+	ut_params->cipher_xform.next = &ut_params->auth_xform;
+
+	ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC;
+	ut_params->cipher_xform.cipher.op = RTE_CRYPTO_SYM_CIPHER_OP_ENCRYPT;
+	ut_params->cipher_xform.cipher.key.data = aes_cbc_key;
+	ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC;
 
 	/* Setup HMAC Parameters */
-	ut_params->hash_params.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_GENERATE;
-	ut_params->hash_params.algo = RTE_CRYPTO_SYM_HASH_SHA512_HMAC;
-	ut_params->hash_params.auth_key.length = HMAC_KEY_LENGTH_SHA512;
-	ut_params->hash_params.auth_key.data = hmac_sha512_key;
-	ut_params->hash_params.digest_length = DIGEST_BYTE_LENGTH_SHA512;
+	ut_params->auth_xform.type = RTE_CRYPTO_XFORM_AUTH;
+	ut_params->auth_xform.next = NULL;
+
+	ut_params->auth_xform.auth.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_GENERATE;
+	ut_params->auth_xform.auth.algo = RTE_CRYPTO_SYM_HASH_SHA512_HMAC;
+	ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA512;
+	ut_params->auth_xform.auth.key.data = hmac_sha512_key;
+	ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA512;
 
 	/* Create Crypto session*/
 	ut_params->sess = rte_cryptodev_session_create(ts_params->valid_devs[0],
-			&ut_params->cipher_params, &ut_params->hash_params,
-			RTE_CRYPTO_SYM_OPCHAIN_CIPHER_HASH);
+			&ut_params->cipher_xform);
 
 	TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
 
@@ -931,8 +1057,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_digest_verify(void)
 
 	/* Create Crypto session*/
 	ut_params->sess = rte_cryptodev_session_create(ts_params->valid_devs[0],
-			&ut_params->cipher_params, &ut_params->hash_params,
-			RTE_CRYPTO_SYM_OPCHAIN_HASH_CIPHER);
+			&ut_params->auth_xform);
 	TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
 
 	return test_AES_CBC_HMAC_SHA512_decrypt_perform(ut_params->sess,
@@ -944,17 +1069,23 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(struct crypto_unittest_pa
 {
 
 	/* Setup Cipher Parameters */
-	ut_params->cipher_params.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC;
-	ut_params->cipher_params.op = RTE_CRYPTO_SYM_CIPHER_OP_DECRYPT;
-	ut_params->cipher_params.key.data = aes_cbc_key;
-	ut_params->cipher_params.key.length = CIPHER_KEY_LENGTH_AES_CBC;
+	ut_params->cipher_xform.type = RTE_CRYPTO_XFORM_CIPHER;
+	ut_params->cipher_xform.next = NULL;
+
+	ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_SYM_CIPHER_AES_CBC;
+	ut_params->cipher_xform.cipher.op = RTE_CRYPTO_SYM_CIPHER_OP_DECRYPT;
+	ut_params->cipher_xform.cipher.key.data = aes_cbc_key;
+	ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC;
 
 	/* Setup HMAC Parameters */
-	ut_params->hash_params.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_VERIFY;
-	ut_params->hash_params.algo = RTE_CRYPTO_SYM_HASH_SHA512_HMAC;
-	ut_params->hash_params.auth_key.data = hmac_sha512_key;
-	ut_params->hash_params.auth_key.length = HMAC_KEY_LENGTH_SHA512;
-	ut_params->hash_params.digest_length = DIGEST_BYTE_LENGTH_SHA512;
+	ut_params->auth_xform.type = RTE_CRYPTO_XFORM_AUTH;
+	ut_params->auth_xform.next = &ut_params->cipher_xform;
+
+	ut_params->auth_xform.auth.op = RTE_CRYPTO_SYM_HASH_OP_DIGEST_VERIFY;
+	ut_params->auth_xform.auth.algo = RTE_CRYPTO_SYM_HASH_SHA512_HMAC;
+	ut_params->auth_xform.auth.key.data = hmac_sha512_key;
+	ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA512;
+	ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA512;
 	return TEST_SUCCESS;
 }
 
@@ -1047,6 +1178,11 @@ static struct unit_test_suite cryptodev_testsuite  = {
 		TEST_CASE_ST(ut_setup, ut_teardown, test_AES_CBC_HMAC_SHA512_encrypt_digest),
 		TEST_CASE_ST(ut_setup, ut_teardown, test_AES_CBC_HMAC_SHA512_decrypt_digest_verify),
 
+		TEST_CASE_ST(ut_setup, ut_teardown, test_AES_CBC_HMAC_AES_XCBC_encrypt_digest),
+		TEST_CASE_ST(ut_setup, ut_teardown, test_AES_CBC_HMAC_AES_XCBC_decrypt_digest_verify),
+
+		TEST_CASE_ST(ut_setup, ut_teardown, test_AES_CBC_HMAC_SHA1_encrypt_digest_sessionless),
+
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
drivers/crypto/aesni_mb/aesni_mb_ops.h +1 -1
index ab96990..1188278 100644
@@ -59,7 +59,7 @@ typedef void (*aes_keyexp_128_t)(void *key, void *enc_exp_keys, void *dec_exp_ke
 typedef void (*aes_keyexp_192_t)(void *key, void *enc_exp_keys, void *dec_exp_keys);
 typedef void (*aes_keyexp_256_t)(void *key, void *enc_exp_keys, void *dec_exp_keys);
 
-typedef void (*aes_xcbc_expand_key_t)(void *key, void *k1_exp, void *k2, void *k3);
+typedef void (*aes_xcbc_expand_key_t)(void *key, void *exp_k1, void *k2, void *k3);
 
 typedef void (*aesni_gcm_t)(gcm_data *my_ctx_data, u8 *out, const u8 *in,
 		u64 plaintext_len, u8 *iv, const u8 *aad, u64 aad_len,
drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c +130 -58

261 lines not on this page · raw message

drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c +4 -6
index fb57e7b..d9cdd5b 100644
@@ -286,9 +286,7 @@ aesni_mb_pmd_session_mempool_create(struct rte_cryptodev *dev,
 
 static struct rte_cryptodev_session *
 aesni_mb_pmd_create_session(struct rte_cryptodev *dev,
-		struct rte_crypto_cipher_params *cipher_setup_data,
-		struct rte_crypto_hash_params *hash_setup_data,
-		enum rte_crypto_operation_chain op_chain)
+		struct rte_crypto_xform *xform)
 {
 	struct aesni_mb_private *internals = dev->data->dev_private;
 	struct aesni_mb_session *sess  =
@@ -299,9 +297,9 @@ aesni_mb_pmd_create_session(struct rte_cryptodev *dev,
 		return NULL;
 	}
 
-	if (aesni_mb_set_session_parameters(
-			&job_ops[internals->vector_mode], sess,
-			cipher_setup_data, hash_setup_data, op_chain) != 0) {
+	if (aesni_mb_set_session_parameters(&job_ops[internals->vector_mode],
+			sess, xform) != 0) {
+		MB_LOG_ERR("failed configure session parameters");
 		aesni_mb_free_session(internals->sess_mp, sess);
 	}
 
drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h +18 -10
index c5c4a86..abfec16 100644
@@ -178,13 +178,21 @@ struct aesni_mb_session {
 
 	struct {
 		JOB_HASH_ALG algo;	/** Authentication Algorithm */
-
-		struct {
-			uint8_t inner[128] __rte_align(16);	/**< inner pad */
-			uint8_t outer[128] __rte_align(16);	/**< outer pad */
-		} pads;
-		/** HMAC Authentication pads - allocating space for the maximum
-		 * pad size supported which is 128 bytes for SHA512 */
+		union {
+			struct {
+				uint8_t inner[128] __rte_align(16);	/**< inner pad */
+				uint8_t outer[128] __rte_align(16);	/**< outer pad */
+			} pads;
+			/** HMAC Authentication pads - allocating space for the maximum
+			 * pad size supported which is 128 bytes for SHA512 */
+
+			struct {
+			    uint32_t k1_expanded[44] __rte_align(16);	/* k1 (expanded key). */
+			    uint8_t k2[16] __rte_align(16);		/* k2. */
+			    uint8_t k3[16] __rte_align(16);		/* k3. */
+			} xcbc;
+			/** Expanded XCBC authentication keys */
+		};
 
 		uint8_t digest[64] __rte_align(16);
 	} auth;	/**< Authentication Parameters */
@@ -212,10 +220,10 @@ aesni_mb_free_session(struct rte_mempool *mempool,
 extern int
 aesni_mb_set_session_parameters(const struct aesni_mb_ops *mb_ops,
 		struct aesni_mb_session *sess,
-		struct rte_crypto_cipher_params *cparams,
-		struct rte_crypto_hash_params *aparams,
-		enum rte_crypto_operation_chain op_chain);
+		const struct rte_crypto_xform *xform);
+
 
+/** device specific operations function pointer structure */
 extern struct rte_cryptodev_ops *rte_aesni_mb_pmd_ops;
 
 
lib/librte_cryptodev/rte_crypto.h +102 -39

217 lines not on this page · raw message

lib/librte_cryptodev/rte_cryptodev.c +33 -21

124 lines not on this page · raw message

lib/librte_cryptodev/rte_cryptodev.h +9 -17
index d7694ad..d2d34f2 100644
@@ -501,31 +501,23 @@ rte_cryptodev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
  * parameters of symmetric cryptographic operation.
  * To perform the operation the rte_cryptodev_enqueue_burst function is
  * used.  Each mbuf should contain a reference to the session
- * pointer returned from this function.
- * Memory to contain the session information is allocated by the
- * implementation.
- * An upper limit on the number of session that many be created is
- * defined by a build configuration constant.
+ * pointer returned from this function contained within it's crypto_op if a
+ * session-based operation is being provisioned. Memory to contain the session
+ * information is allocated from within mempool managed by the cryptodev.
+ *
  * The rte_cryptodev_session_free must be called to free allocated
- * memory when the session information is no longer needed.
+ * memory when the session is no longer required.
  *
- * @param	dev_id			The device identifier.
- * @param	cipher_setup_data	The parameters associated with the
- *					cipher operation. This may be NULL.
- * @param	hash_setup_data		The parameters associated with the hash
- *					operation. This may be NULL.
- * @param	op_chain		Specifies the crypto operation chaining,
- *					cipher and/or hash and the order in
- *					which they are performed.
+ * @param	dev_id		The device identifier.
+ * @param	xform		Crypto transform chain.
+
  *
  * @return
  *  Pointer to the created session or NULL
  */
 extern struct rte_cryptodev_session *
 rte_cryptodev_session_create(uint8_t dev_id,
-		struct rte_crypto_cipher_params *cipher_setup_data,
-		struct rte_crypto_hash_params *hash_setup_data,
-		enum rte_crypto_operation_chain op_chain);
+		struct rte_crypto_xform *xform);
 
 
 /**
lib/librte_cryptodev/rte_cryptodev_pmd.h +3 -7
index e6fdd1c..aa2f6c4 100644
@@ -453,10 +453,8 @@ typedef int (*cryptodev_create_session_pool_t)(
 /**
  * Create a Crypto session on a device.
  *
- * @param	dev			Crypto device pointer
- * @param	cipher_setup_data	Cipher operation parameters
- * @param	hash_setup_data		Hash operation parameters
- * @param	op_chain		Operation chaining
+ * @param	dev		Crypto device pointer
+ * @param	xform		Single or chain of crypto xforms
  *
  * @return
  *  - Returns cryptodev session structure on success.
@@ -464,9 +462,7 @@ typedef int (*cryptodev_create_session_pool_t)(
  * */
 typedef struct rte_cryptodev_session * (*cryptodev_create_session_t)(
 		struct rte_cryptodev *dev,
-		struct rte_crypto_cipher_params *cipher_setup_data,
-		struct rte_crypto_hash_params *hash_setup_data,
-		enum rte_crypto_operation_chain op_chain);
+		struct rte_crypto_xform *xform);
 
 /**
  * Free Crypto session.
Signature · 1 line
2.4.3
#5 lore raw

PATCH 2/4 qat_crypto_pmd: Addition of a new QAT DPDK PMD.

In reply to Declan Doherty

From: John Griffin <[email protected]>

This patch adds a PMD for the Intel Quick Assist Technology DH895xxC hardware accelerator.
This PMD will adhere to the cryptodev API (contained in a previous patch). This patch depends on a QAT PF driver which may be downloaded from 01.org (please see the file qat_pf_driver_install.txt contained in this patch).

This is a limited patchset which has support for a chain of cipher and hash the following algorithms are supported:
Cipher algorithms:

 -   RTE_CRYPTO_SYM_CIPHER_AES128_CBC
 -   RTE_CRYPTO_SYM_CIPHER_AES256_CBC
 -   RTE_CRYPTO_SYM_CIPHER_AES512_CBC
Hash algorithms:
 -   RTE_CRYPTO_SYM_HASH_SHA1_HMAC
 -   RTE_CRYPTO_SYM_HASH_SHA256_HMAC
 -   RTE_CRYPTO_SYM_HASH_SHA512_HMAC

Some limitation on this patchset which shall be contributed in a subsequent release:

 -   Chained mbufs are not supported.
 -   Hash only is not supported.
 -   Cipher only is not supported.
 -   Only in-place is currently supported (destination address is the

same as source address).
- Only supports session-oriented API implementation (session-less
APIs are not supported).
- Not performance tuned.

---
 config/common_bsdapp                               |  13 +
 config/common_linuxapp                             |  15 +-
 doc/guides/cryptodevs/index.rst                    |  42 ++
 doc/guides/cryptodevs/qat.rst                      | 155 +++++++
 doc/guides/index.rst                               |   1 +
 drivers/Makefile                                   |   1 +
 drivers/crypto/Makefile                            |  38 ++
 drivers/crypto/qat/Makefile                        |  63 +++
 .../qat/qat_adf/adf_transport_access_macros.h      | 173 ++++++++
 drivers/crypto/qat/qat_adf/icp_qat_fw.h            | 316 ++++++++++++++
 drivers/crypto/qat/qat_adf/icp_qat_fw_la.h         | 404 ++++++++++++++++++
 drivers/crypto/qat/qat_adf/icp_qat_hw.h            | 305 ++++++++++++++
 drivers/crypto/qat/qat_adf/qat_algs.h              | 124 ++++++
 drivers/crypto/qat/qat_adf/qat_algs_build_desc.c   | 462 ++++++++++++++++++++
 drivers/crypto/qat/qat_crypto.c                    | 469 +++++++++++++++++++++
 drivers/crypto/qat/qat_crypto.h                    |  99 +++++
 drivers/crypto/qat/qat_logs.h                      |  78 ++++
 drivers/crypto/qat/qat_qp.c                        | 372 ++++++++++++++++
 drivers/crypto/qat/rte_pmd_qat_version.map         |   5 +
 drivers/crypto/qat/rte_qat_cryptodev.c             | 128 ++++++
 mk/rte.app.mk                                      |   3 +
 21 files changed, 3265 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/cryptodevs/index.rst
 create mode 100644 doc/guides/cryptodevs/qat.rst
 create mode 100644 drivers/crypto/Makefile
 create mode 100644 drivers/crypto/qat/Makefile
 create mode 100644 drivers/crypto/qat/qat_adf/adf_transport_access_macros.h
 create mode 100644 drivers/crypto/qat/qat_adf/icp_qat_fw.h
 create mode 100644 drivers/crypto/qat/qat_adf/icp_qat_fw_la.h
 create mode 100644 drivers/crypto/qat/qat_adf/icp_qat_hw.h
 create mode 100644 drivers/crypto/qat/qat_adf/qat_algs.h
 create mode 100644 drivers/crypto/qat/qat_adf/qat_algs_build_desc.c
 create mode 100644 drivers/crypto/qat/qat_crypto.c
 create mode 100644 drivers/crypto/qat/qat_crypto.h
 create mode 100644 drivers/crypto/qat/qat_logs.h
 create mode 100644 drivers/crypto/qat/qat_qp.c
 create mode 100644 drivers/crypto/qat/rte_pmd_qat_version.map
 create mode 100644 drivers/crypto/qat/rte_qat_cryptodev.c
config/common_bsdapp +13 -0
index ed30180..8fcc004 100644
@@ -154,6 +154,19 @@ CONFIG_RTE_LIBRTE_CRYPTODEV_DEBUG=y
 CONFIG_RTE_MAX_CRYPTOPORTS=32
 
 #
+# Compile PMD for QuickAssist based devices
+#
+CONFIG_RTE_LIBRTE_PMD_QAT=y
+CONFIG_RTE_LIBRTE_QAT_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_QAT_DEBUG_TX=y
+CONFIG_RTE_LIBRTE_QAT_DEBUG_RX=y
+CONFIG_RTE_LIBRTE_QAT_DEBUG_DRIVER=y
+#
+# Number of sessions to create in the session memory pool
+# on a single QuickAssist device.
+#
+CONFIG_RTE_MAX_QAT_SESSIONS=200
+
 # Support NIC bypass logic
 #
 CONFIG_RTE_NIC_BYPASS=n
config/common_linuxapp +14 -1
index 12a75c6..7199c95 100644
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -152,6 +152,19 @@ CONFIG_RTE_LIBRTE_CRYPTODEV_DEBUG=y
 CONFIG_RTE_MAX_CRYPTODEVS=64
 
 #
+# Compile PMD for QuickAssist based devices
+#
+CONFIG_RTE_LIBRTE_PMD_QAT=y
+CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_TX=y
+CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_RX=y
+CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_DRIVER=y
+#
+# Number of sessions to create in the session memory pool
+# on a single QuickAssist device.
+#
+CONFIG_RTE_LIBRTE_PMD_QAT_MAX_SESSIONS=4096
+
 # Support NIC bypass logic
 #
 CONFIG_RTE_NIC_BYPASS=n
doc/guides/cryptodevs/index.rst new file +42 -0

42 lines not on this page · raw message

doc/guides/cryptodevs/qat.rst new file +155 -0

155 lines not on this page · raw message

doc/guides/index.rst +1 -0
index 439c7e3..c5d7a9f 100644
@@ -42,6 +42,7 @@ Contents:
    xen/index
    prog_guide/index
    nics/index
+   cryptodevs/index
    sample_app_ug/index
    testpmd_app_ug/index
    faq/index
drivers/Makefile +1 -0
index b60eb5e..6ec67f6 100644
@@ -32,5 +32,6 @@
 include $(RTE_SDK)/mk/rte.vars.mk
 
 DIRS-y += net
+DIRS-y += crypto
 
 include $(RTE_SDK)/mk/rte.subdir.mk
drivers/crypto/Makefile new file +38 -0
new file mode 100644
index 0000000..eeb998e
@@ -0,0 +1,38 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += qat
+
+include $(RTE_SDK)/mk/rte.sharelib.mk
+include $(RTE_SDK)/mk/rte.subdir.mk
drivers/crypto/qat/Makefile new file +63 -0

63 lines not on this page · raw message

drivers/crypto/qat/qat_adf/adf_transport_access_macros.h new file +173 -0

173 lines not on this page · raw message

drivers/crypto/qat/qat_adf/icp_qat_fw.h new file +316 -0

316 lines not on this page · raw message

drivers/crypto/qat/qat_adf/icp_qat_fw_la.h new file +404 -0

404 lines not on this page · raw message

drivers/crypto/qat/qat_adf/icp_qat_hw.h new file +305 -0

305 lines not on this page · raw message

drivers/crypto/qat/qat_adf/qat_algs.h new file +124 -0

124 lines not on this page · raw message

drivers/crypto/qat/qat_adf/qat_algs_build_desc.c new file +462 -0

462 lines not on this page · raw message

drivers/crypto/qat/qat_crypto.c new file +469 -0

469 lines not on this page · raw message

drivers/crypto/qat/qat_crypto.h new file +99 -0

99 lines not on this page · raw message

drivers/crypto/qat/qat_logs.h new file +78 -0

78 lines not on this page · raw message

drivers/crypto/qat/qat_qp.c new file +372 -0

214 lines not on this page · raw message

drivers/crypto/qat/rte_pmd_qat_version.map new file +5 -0
new file mode 100644
index 0000000..fcf5bb3

Lines of this file are not shown. View the raw message.

drivers/crypto/qat/rte_qat_cryptodev.c new file +128 -0

128 lines not on this page · raw message

mk/rte.app.mk +3 -0
index c7ee033..5502cc4 100644

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Signature · 1 line
1.9.3

Part of the diff is not shown here. View the raw message.

#6 lore raw

PATCH 3/4 aesni_mb_pmd: Initial implementation of multi buffer based crypto device

In reply to Declan Doherty

This patch provides the initial implementation of the AES-NI multi-buffer based crypto poll mode driver using DPDK's new cryptodev framework. This PMD is dependent on Intel's multibuffer library, see the white paper "Fast Multi-buffer IPsec Implementations on Intel® Architecture Processors", see ref 1 for details on the library's design and ref 2 to download the library itself. This initial implementation is limited to supporting the chained operations of "hash then cipher" or "cipher then hash" for the following cipher and hash algorithms:

- RTE_CRYPTO_SYM_CIPHER_AES128_CBC
- RTE_CRYPTO_SYM_CIPHER_AES256_CBC
- RTE_CRYPTO_SYM_CIPHER_AES512_CBC
- RTE_CRYPTO_SYM_HASH_SHA1_HMAC
- RTE_CRYPTO_SYM_HASH_SHA256_HMAC
- RTE_CRYPTO_SYM_HASH_SHA512_HMAC

Important Note:
Due to the fact that the multi-buffer library is designed for accelerating IPsec crypto oepration, the digest's generated for the HMAC functions are truncated to lengths specified by IPsec RFC's, ie RFC2404 for using HMAC-SHA-1 with IPsec specifies that the digest is truncate from 20 to 12 bytes.

Build instructions:
To build DPKD with the AESNI_MB_PMD the user is required to download (ref 2) and compile the multi-buffer library on there user system before building DPDK. The environmental variable AESNI_MULTI_BUFFER_LIB_PATH must be exported with the path where you extracted and built the multi buffer library and finally set CONFIG_RTE_LIBRTE_PMD_AESNI_MB=y in config/common_linuxapp.

Current status: This is a work in progress, which has not been performance tuned. The software has only been built and tested on Fedora 20 64-bit using gcc. It's doesn't support crypto operation across chained mbufs, or cipher only or hash only operations.

ref 1:
https://www-ssl.intel.com/content/www/us/en/intelligent-systems/intel-technology/fast-multi-buffer-ipsec-implementations-ia-processors-p

ref 2: https://downloadcenter.intel.com/download/22972

---
 config/common_bsdapp                               |   8 +
 config/common_linuxapp                             |   7 +
 doc/guides/cryptodevs/aesni_mb.rst                 |  76 +++
 doc/guides/cryptodevs/index.rst                    |   1 +
 drivers/crypto/Makefile                            |   2 +-
 drivers/crypto/aesni_mb/Makefile                   |  67 +++
 drivers/crypto/aesni_mb/aesni_mb_ops.h             | 206 ++++++++
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c         | 550 +++++++++++++++++++++
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c     | 346 +++++++++++++
 drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h | 224 +++++++++
 drivers/crypto/aesni_mb/rte_pmd_aesni_version.map  |   5 +
 mk/rte.app.mk                                      |   4 +
 12 files changed, 1495 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/cryptodevs/aesni_mb.rst
 create mode 100644 drivers/crypto/aesni_mb/Makefile
 create mode 100644 drivers/crypto/aesni_mb/aesni_mb_ops.h
 create mode 100644 drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
 create mode 100644 drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c
 create mode 100644 drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
 create mode 100644 drivers/crypto/aesni_mb/rte_pmd_aesni_version.map
config/common_bsdapp +8 -0
index 8fcc004..9c5e1e0 100644
@@ -167,6 +167,14 @@ CONFIG_RTE_LIBRTE_QAT_DEBUG_DRIVER=y
 #
 CONFIG_RTE_MAX_QAT_SESSIONS=200
 
+
+#
+# Compile PMD for AESNI backed device
+#
+CONFIG_RTE_LIBRTE_PMD_AESNI_MB=y
+CONFIG_RTE_LIBRTE_AESNI_MB_DEBUG=n
+
+#
 # Support NIC bypass logic
 #
 CONFIG_RTE_NIC_BYPASS=n
config/common_linuxapp +7 -0
index 7199c95..8e9e8fd 100644
@@ -165,6 +165,13 @@ CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_DRIVER=y
 #
 CONFIG_RTE_LIBRTE_PMD_QAT_MAX_SESSIONS=4096
 
+# Compile PMD for AESNI backed device
+#
+CONFIG_RTE_LIBRTE_PMD_AESNI_MB=y
+CONFIG_RTE_LIBRTE_PMD_AESNI_MB_DEBUG=n
+CONFIG_RTE_LIBRTE_PMD_AESNI_MB_MAX_SESSIONS=2048
+
+#
 # Support NIC bypass logic
 #
 CONFIG_RTE_NIC_BYPASS=n
doc/guides/cryptodevs/aesni_mb.rst new file +76 -0

77 lines not on this page · raw message

doc/guides/cryptodevs/index.rst +1 -0
index 1c31697..8949fd0 100644
@@ -39,4 +39,5 @@ Crypto Device Drivers
     :maxdepth: 2
     :numbered:
 
+    aesni_mb
     qat
drivers/crypto/Makefile +1 -1
index eeb998e..26325b0 100644
@@ -31,7 +31,7 @@
 
 include $(RTE_SDK)/mk/rte.vars.mk
 
-
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += qat
 
 include $(RTE_SDK)/mk/rte.sharelib.mk
drivers/crypto/aesni_mb/Makefile new file +67 -0

67 lines not on this page · raw message

drivers/crypto/aesni_mb/aesni_mb_ops.h new file +206 -0

206 lines not on this page · raw message

drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c new file +550 -0

550 lines not on this page · raw message

drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c new file +346 -0

346 lines not on this page · raw message

drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h new file +224 -0

224 lines not on this page · raw message

drivers/crypto/aesni_mb/rte_pmd_aesni_version.map new file +5 -0
new file mode 100644
index 0000000..39cc84f
@@ -0,0 +1,5 @@
+DPDK_2.2 {
+	global:
+
+	local: *;
+};
mk/rte.app.mk +4 -0
index 5502cc4..496cbeb 100644
@@ -148,6 +148,10 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL)       += -lrte_pmd_null
 # QAT PMD has a dependancy on libcrypto (from openssl) for calculating HMAC precomputes
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT)        += -lrte_pmd_qat -lcrypto
 
+# AESNI MULTI BUFFER is dependent on the IPSec_MB library
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB)   += -lrte_pmd_aesni_mb
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB)   += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
+
 endif # ! $(CONFIG_RTE_BUILD_SHARED_LIB)
 
 endif # ! CONFIG_RTE_BUILD_COMBINE_LIBS
Signature · 1 line
1.9.3
#7 lore raw

PATCH 4/4 app/test: add cryptodev unit and performance tests

In reply to Declan Doherty

unit tests are run by using cryptodev_qat_autotest or cryptodev_aesni_autotest from the test apps interactive console.

performance tests are run by using the cryptodev_qat_perftest or cryptodev_aesni_mb_perftest command from the test apps interactive console.

If you which to run the tests on a QAT device there must be one bound to igb_uio kernel driver.

---
 app/test/Makefile                  |    7 +-
 app/test/test.c                    |   91 ++-
 app/test/test.h                    |   34 +-
 app/test/test_cryptodev.c          | 1079 +++++++++++++++++++++++++++
 app/test/test_cryptodev_perf.c     | 1438 ++++++++++++++++++++++++++++++++++++
 app/test/test_link_bonding.c       |    6 +-
 app/test/test_link_bonding_mode4.c |    7 +-
 7 files changed, 2616 insertions(+), 46 deletions(-)
 create mode 100644 app/test/test_cryptodev.c
 create mode 100644 app/test/test_cryptodev_perf.c
app/test/Makefile +5 -2
index e7f148f..0812487 100644
@@ -140,11 +140,14 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += test_link_bonding.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += test_link_bonding_mode4.c
 endif
 
+SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_perf.c
+SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev.c
+
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring.c
 SRCS-$(CONFIG_RTE_LIBRTE_KVARGS) += test_kvargs.c
 
-CFLAGS += -O3
-CFLAGS += $(WERROR_FLAGS)
+#CFLAGS += -O3
+CFLAGS += -g -O0 $(WERROR_FLAGS)
 
 # Disable warnings of deprecated-declarations in test_kni.c
 ifeq ($(CC), icc)
app/test/test.c +61 -30

112 lines not on this page · raw message

app/test/test.h +27 -7
index 62eb51d..a2b33c0 100644
@@ -33,7 +33,7 @@
 
 #ifndef _TEST_H_
 #define _TEST_H_
-
+#include <stddef.h>
 #include <sys/queue.h>
 
 #define TEST_SUCCESS  (0)
@@ -64,6 +64,17 @@
 		}                                                        \
 } while (0)
 
+
+#define TEST_ASSERT_BUFFERS_ARE_EQUAL(a, b, len,  msg, ...) do {	\
+	if (memcmp(a, b,len)) {                                         \
+		printf("TestCase %s() line %d failed: "              \
+			msg "\n", __func__, __LINE__, ##__VA_ARGS__);    \
+		TEST_TRACE_FAILURE(__FILE__, __LINE__, __func__);    \
+		return TEST_FAILED;                                  \
+	}                                                        \
+} while (0)
+
+
 #define TEST_ASSERT_NOT_EQUAL(a, b, msg, ...) do {               \
 		if (!(a != b)) {                                         \
 			printf("TestCase %s() line %d failed: "              \
@@ -113,27 +124,36 @@
 
 struct unit_test_case {
 	int (*setup)(void);
-	int (*teardown)(void);
+	void (*teardown)(void);
 	int (*testcase)(void);
 	const char *success_msg;
 	const char *fail_msg;
+	unsigned enabled;
 };
 
-#define TEST_CASE(fn) { NULL, NULL, fn, #fn " succeeded", #fn " failed"}
+#define TEST_CASE(fn) { NULL, NULL, fn, #fn " succeeded", #fn " failed", 1 }
 
 #define TEST_CASE_NAMED(name, fn) { NULL, NULL, fn, name " succeeded", \
-		name " failed"}
+		name " failed", 1}
 
 #define TEST_CASE_ST(setup, teardown, testcase)         \
 		{ setup, teardown, testcase, #testcase " succeeded",    \
-		#testcase " failed "}
+		#testcase " failed ", 1}
+
+
+#define TEST_CASE_DISABLED(fn) { NULL, NULL, fn, #fn " succeeded", \
+	#fn " failed", 0 }
+
+#define TEST_CASE_ST_DISABLED(setup, teardown, testcase)         \
+		{ setup, teardown, testcase, #testcase " succeeded",    \
+		#testcase " failed ", 0 }
 
-#define TEST_CASES_END() { NULL, NULL, NULL, NULL, NULL }
+#define TEST_CASES_END() { NULL, NULL, NULL, NULL, NULL, 0 }
 
 struct unit_test_suite {
 	const char *suite_name;
 	int (*setup)(void);
-	int (*teardown)(void);
+	void (*teardown)(void);
 	struct unit_test_case unit_test_cases[];
 };
 
app/test/test_cryptodev.c new file +1079 -0

1,079 lines not on this page · raw message

app/test/test_cryptodev_perf.c new file +1438 -0

1,438 lines not on this page · raw message

app/test/test_link_bonding.c +3 -3
index 388cf11..2d98958 100644
@@ -4020,7 +4020,7 @@ test_close_bonded_device(void)
 	return 0;
 }
 
-static int
+static void
 testsuite_teardown(void)
 {
 	if (test_params->pkt_eth_hdr != NULL) {
@@ -4029,7 +4029,7 @@ testsuite_teardown(void)
 	}
 
 	/* Clean up and remove slaves from bonded device */
-	return remove_slaves_and_stop_bonded_device();
+	remove_slaves_and_stop_bonded_device();
 }
 
 static void
@@ -4993,7 +4993,7 @@ static struct unit_test_suite link_bonding_test_suite  = {
 		TEST_CASE(test_reconfigure_bonded_device),
 		TEST_CASE(test_close_bonded_device),
 
-		{ NULL, NULL, NULL, NULL, NULL } /**< NULL terminate unit test array */
+		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
 
app/test/test_link_bonding_mode4.c +3 -4
index 460539d..713368d 100644
@@ -453,7 +453,7 @@ test_setup(void)
 	return 0;
 }
 
-static int
+static void
 testsuite_teardown(void)
 {
 	struct slave_conf *port;
@@ -467,8 +467,6 @@ testsuite_teardown(void)
 
 	FOR_EACH_PORT(i, port)
 		rte_eth_dev_stop(port->port_id);
-
-	return 0;
 }
 
 /*
@@ -1390,7 +1388,8 @@ static struct unit_test_suite link_bonding_mode4_test_suite  = {
 		TEST_CASE_NAMED("test_mode4_tx_burst", test_mode4_tx_burst_wrapper),
 		TEST_CASE_NAMED("test_mode4_marker", test_mode4_marker_wrapper),
 		TEST_CASE_NAMED("test_mode4_expired", test_mode4_expired_wrapper),
-		{ NULL, NULL, NULL, NULL, NULL } /**< NULL terminate unit test array */
+
+		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
 
Signature · 1 line
1.9.3