xref: /dpdk/doc/guides/prog_guide/cryptodev_lib.rst (revision decb35d890209f603b01c1d23f35995bd51228fc)
1..  SPDX-License-Identifier: BSD-3-Clause
2    Copyright(c) 2016-2020 Intel Corporation.
3
4Cryptography Device Library
5===========================
6
7The cryptodev library provides a Crypto device framework for management and
8provisioning of hardware and software Crypto poll mode drivers, defining generic
9APIs which support a number of different Crypto operations. The framework
10currently only supports cipher, authentication, chained cipher/authentication
11and AEAD symmetric and asymmetric Crypto operations.
12
13
14Design Principles
15-----------------
16
17The cryptodev library follows the same basic principles as those used in DPDK's
18Ethernet Device framework. The Crypto framework provides a generic Crypto device
19framework which supports both physical (hardware) and virtual (software) Crypto
20devices as well as a generic Crypto API which allows Crypto devices to be
21managed and configured and supports Crypto operations to be provisioned on
22Crypto poll mode driver.
23
24
25Device Management
26-----------------
27
28Device Creation
29~~~~~~~~~~~~~~~
30
31Physical Crypto devices are discovered during the PCI probe/enumeration of the
32EAL function which is executed at DPDK initialization, based on
33their PCI device identifier, each unique PCI BDF (bus/bridge, device,
34function). Specific physical Crypto devices, like other physical devices in DPDK
35can be listed using the EAL command line options.
36
37Virtual devices can be created by two mechanisms, either using the EAL command
38line options or from within the application using an EAL API directly.
39
40From the command line using the --vdev EAL option
41
42.. code-block:: console
43
44   --vdev  'crypto_aesni_mb0,max_nb_queue_pairs=2,socket_id=0'
45
46.. Note::
47
48   * If DPDK application requires multiple software crypto PMD devices then required
49     number of ``--vdev`` with appropriate libraries are to be added.
50
51   * An Application with crypto PMD instances sharing the same library requires unique ID.
52
53   Example: ``--vdev  'crypto_aesni_mb0' --vdev  'crypto_aesni_mb1'``
54
55Or using the rte_vdev_init API within the application code.
56
57.. code-block:: c
58
59   rte_vdev_init("crypto_aesni_mb",
60                     "max_nb_queue_pairs=2,socket_id=0")
61
62All virtual Crypto devices support the following initialization parameters:
63
64* ``max_nb_queue_pairs`` - maximum number of queue pairs supported by the device.
65* ``socket_id`` - socket on which to allocate the device resources on.
66
67
68Device Identification
69~~~~~~~~~~~~~~~~~~~~~
70
71Each device, whether virtual or physical is uniquely designated by two
72identifiers:
73
74- A unique device index used to designate the Crypto device in all functions
75  exported by the cryptodev API.
76
77- A device name used to designate the Crypto device in console messages, for
78  administration or debugging purposes. For ease of use, the port name includes
79  the port index.
80
81
82Device Configuration
83~~~~~~~~~~~~~~~~~~~~
84
85The configuration of each Crypto device includes the following operations:
86
87- Allocation of resources, including hardware resources if a physical device.
88- Resetting the device into a well-known default state.
89- Initialization of statistics counters.
90
91The rte_cryptodev_configure API is used to configure a Crypto device.
92
93.. code-block:: c
94
95   int rte_cryptodev_configure(uint8_t dev_id,
96                               struct rte_cryptodev_config *config)
97
98The ``rte_cryptodev_config`` structure is used to pass the configuration
99parameters for socket selection and number of queue pairs.
100
101.. code-block:: c
102
103    struct rte_cryptodev_config {
104        int socket_id;
105        /**< Socket to allocate resources on */
106        uint16_t nb_queue_pairs;
107        /**< Number of queue pairs to configure on device */
108    };
109
110
111Configuration of Queue Pairs
112~~~~~~~~~~~~~~~~~~~~~~~~~~~~
113
114Each Crypto devices queue pair is individually configured through the
115``rte_cryptodev_queue_pair_setup`` API.
116Each queue pairs resources may be allocated on a specified socket.
117
118.. code-block:: c
119
120    int rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
121                const struct rte_cryptodev_qp_conf *qp_conf,
122                int socket_id)
123
124   struct rte_cryptodev_qp_conf {
125        uint32_t nb_descriptors; /**< Number of descriptors per queue pair */
126        struct rte_mempool *mp_session;
127        /**< The mempool for creating session in sessionless mode */
128        struct rte_mempool *mp_session_private;
129        /**< The mempool for creating sess private data in sessionless mode */
130    };
131
132
133The fields ``mp_session`` and ``mp_session_private`` are used for creating
134temporary session to process the crypto operations in the session-less mode.
135They can be the same other different mempools. Please note not all Cryptodev
136PMDs supports session-less mode.
137
138
139Logical Cores, Memory and Queues Pair Relationships
140~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
141
142The Crypto device Library as the Poll Mode Driver library support NUMA for when
143a processor’s logical cores and interfaces utilize its local memory. Therefore
144Crypto operations, and in the case of symmetric Crypto operations, the session
145and the mbuf being operated on, should be allocated from memory pools created
146in the local memory. The buffers should, if possible, remain on the local
147processor to obtain the best performance results and buffer descriptors should
148be populated with mbufs allocated from a mempool allocated from local memory.
149
150The run-to-completion model also performs better, especially in the case of
151virtual Crypto devices, if the Crypto operation and session and data buffer is
152in local memory instead of a remote processor's memory. This is also true for
153the pipe-line model provided all logical cores used are located on the same
154processor.
155
156Multiple logical cores should never share the same queue pair for enqueuing
157operations or dequeuing operations on the same Crypto device since this would
158require global locks and hinder performance. It is however possible to use a
159different logical core to dequeue an operation on a queue pair from the logical
160core which it was enqueued on. This means that a crypto burst enqueue/dequeue
161APIs are a logical place to transition from one logical core to another in a
162packet processing pipeline.
163
164
165Device Features and Capabilities
166---------------------------------
167
168Crypto devices define their functionality through two mechanisms, global device
169features and algorithm capabilities. Global devices features identify device
170wide level features which are applicable to the whole device such as
171the device having hardware acceleration or supporting symmetric and/or asymmetric
172Crypto operations.
173
174The capabilities mechanism defines the individual algorithms/functions which
175the device supports, such as a specific symmetric Crypto cipher,
176authentication operation or Authenticated Encryption with Associated Data
177(AEAD) operation.
178
179
180Device Features
181~~~~~~~~~~~~~~~
182
183Currently the following Crypto device features are defined:
184
185* Symmetric Crypto operations
186* Asymmetric Crypto operations
187* Chaining of symmetric Crypto operations
188* SSE accelerated SIMD vector operations
189* AVX accelerated SIMD vector operations
190* AVX2 accelerated SIMD vector operations
191* AESNI accelerated instructions
192* Hardware off-load processing
193
194
195Device Operation Capabilities
196~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
197
198Crypto capabilities which identify particular algorithm which the Crypto PMD
199supports are  defined by the operation type, the operation transform, the
200transform identifier and then the particulars of the transform. For the full
201scope of the Crypto capability see the definition of the structure in the
202*DPDK API Reference*.
203
204.. code-block:: c
205
206   struct rte_cryptodev_capabilities;
207
208Each Crypto poll mode driver defines its own private array of capabilities
209for the operations it supports. Below is an example of the capabilities for a
210PMD which supports the authentication algorithm SHA1_HMAC and the cipher
211algorithm AES_CBC.
212
213.. code-block:: c
214
215    static const struct rte_cryptodev_capabilities pmd_capabilities[] = {
216        {    /* SHA1 HMAC */
217            .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
218            .sym = {
219                .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
220                .auth = {
221                    .algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
222                    .block_size = 64,
223                    .key_size = {
224                        .min = 64,
225                        .max = 64,
226                        .increment = 0
227                    },
228                    .digest_size = {
229                        .min = 12,
230                        .max = 12,
231                        .increment = 0
232                    },
233                    .aad_size = { 0 },
234                    .iv_size = { 0 }
235                }
236            }
237        },
238        {    /* AES CBC */
239            .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
240            .sym = {
241                .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
242                .cipher = {
243                    .algo = RTE_CRYPTO_CIPHER_AES_CBC,
244                    .block_size = 16,
245                    .key_size = {
246                        .min = 16,
247                        .max = 32,
248                        .increment = 8
249                    },
250                    .iv_size = {
251                        .min = 16,
252                        .max = 16,
253                        .increment = 0
254                    }
255                }
256            }
257        }
258    }
259
260
261Capabilities Discovery
262~~~~~~~~~~~~~~~~~~~~~~
263
264Discovering the features and capabilities of a Crypto device poll mode driver
265is achieved through the ``rte_cryptodev_info_get`` function.
266
267.. code-block:: c
268
269   void rte_cryptodev_info_get(uint8_t dev_id,
270                               struct rte_cryptodev_info *dev_info);
271
272This allows the user to query a specific Crypto PMD and get all the device
273features and capabilities. The ``rte_cryptodev_info`` structure contains all the
274relevant information for the device.
275
276.. code-block:: c
277
278    struct rte_cryptodev_info {
279        const char *driver_name;
280        uint8_t driver_id;
281        struct rte_device *device;
282
283        uint64_t feature_flags;
284
285        const struct rte_cryptodev_capabilities *capabilities;
286
287        unsigned max_nb_queue_pairs;
288
289        struct {
290            unsigned max_nb_sessions;
291        } sym;
292    };
293
294
295Operation Processing
296--------------------
297
298Scheduling of Crypto operations on DPDK's application data path is
299performed using a burst oriented asynchronous API set. A queue pair on a Crypto
300device accepts a burst of Crypto operations using enqueue burst API. On physical
301Crypto devices the enqueue burst API will place the operations to be processed
302on the devices hardware input queue, for virtual devices the processing of the
303Crypto operations is usually completed during the enqueue call to the Crypto
304device. The dequeue burst API will retrieve any processed operations available
305from the queue pair on the Crypto device, from physical devices this is usually
306directly from the devices processed queue, and for virtual device's from a
307``rte_ring`` where processed operations are placed after being processed on the
308enqueue call.
309
310
311Private data
312~~~~~~~~~~~~
313For session-based operations, the set and get API provides a mechanism for an
314application to store and retrieve the private user data information stored along
315with the crypto session.
316
317For example, suppose an application is submitting a crypto operation with a session
318associated and wants to indicate private user data information which is required to be
319used after completion of the crypto operation. In this case, the application can use
320the set API to set the user data and retrieve it using get API.
321
322.. code-block:: c
323
324	int rte_cryptodev_sym_session_set_user_data(
325		struct rte_cryptodev_sym_session *sess,	void *data, uint16_t size);
326
327	void * rte_cryptodev_sym_session_get_user_data(
328		struct rte_cryptodev_sym_session *sess);
329
330Please note the ``size`` passed to set API cannot be bigger than the predefined
331``user_data_sz`` when creating the session header mempool, otherwise the
332function will return error. Also when ``user_data_sz`` was defined as ``0`` when
333creating the session header mempool, the get API will always return ``NULL``.
334
335For session-less mode, the private user data information can be placed along with the
336``struct rte_crypto_op``. The ``rte_crypto_op::private_data_offset`` indicates the
337start of private data information. The offset is counted from the start of the
338rte_crypto_op including other crypto information such as the IVs (since there can
339be an IV also for authentication).
340
341User callback APIs
342~~~~~~~~~~~~~~~~~~
343The add APIs configures a user callback function to be called for each burst of crypto
344ops received/sent on a given crypto device queue pair. The return value is a pointer
345that can be used later to remove the callback using remove API. Application is expected
346to register a callback function of type ``rte_cryptodev_callback_fn``. Multiple callback
347functions can be added for a given queue pair. API does not restrict on maximum number of
348callbacks.
349
350Callbacks registered by application would not survive ``rte_cryptodev_configure`` as it
351reinitializes the callback list. It is user responsibility to remove all installed
352callbacks before calling ``rte_cryptodev_configure`` to avoid possible memory leakage.
353
354So, the application is expected to add user callback after ``rte_cryptodev_configure``.
355The callbacks can also be added at the runtime. These callbacks get executed when
356``rte_cryptodev_enqueue_burst``/``rte_cryptodev_dequeue_burst`` is called.
357
358.. code-block:: c
359
360	struct rte_cryptodev_cb *
361		rte_cryptodev_add_enq_callback(uint8_t dev_id, uint16_t qp_id,
362					       rte_cryptodev_callback_fn cb_fn,
363					       void *cb_arg);
364
365	struct rte_cryptodev_cb *
366		rte_cryptodev_add_deq_callback(uint8_t dev_id, uint16_t qp_id,
367					       rte_cryptodev_callback_fn cb_fn,
368					       void *cb_arg);
369
370	uint16_t (* rte_cryptodev_callback_fn)(uint16_t dev_id, uint16_t qp_id,
371					       struct rte_crypto_op **ops,
372					       uint16_t nb_ops, void *user_param);
373
374The remove API removes a callback function added by
375``rte_cryptodev_add_enq_callback``/``rte_cryptodev_add_deq_callback``.
376
377.. code-block:: c
378
379	int rte_cryptodev_remove_enq_callback(uint8_t dev_id, uint16_t qp_id,
380					      struct rte_cryptodev_cb *cb);
381
382	int rte_cryptodev_remove_deq_callback(uint8_t dev_id, uint16_t qp_id,
383					      struct rte_cryptodev_cb *cb);
384
385
386Enqueue / Dequeue Burst APIs
387~~~~~~~~~~~~~~~~~~~~~~~~~~~~
388
389The burst enqueue API uses a Crypto device identifier and a queue pair
390identifier to specify the Crypto device queue pair to schedule the processing on.
391The ``nb_ops`` parameter is the number of operations to process which are
392supplied in the ``ops`` array of ``rte_crypto_op`` structures.
393The enqueue function returns the number of operations it actually enqueued for
394processing, a return value equal to ``nb_ops`` means that all packets have been
395enqueued.
396
397.. code-block:: c
398
399   uint16_t rte_cryptodev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
400                                        struct rte_crypto_op **ops, uint16_t nb_ops)
401
402The dequeue API uses the same format as the enqueue API of processed but
403the ``nb_ops`` and ``ops`` parameters are now used to specify the max processed
404operations the user wishes to retrieve and the location in which to store them.
405The API call returns the actual number of processed operations returned, this
406can never be larger than ``nb_ops``.
407
408.. code-block:: c
409
410   uint16_t rte_cryptodev_dequeue_burst(uint8_t dev_id, uint16_t qp_id,
411                                        struct rte_crypto_op **ops, uint16_t nb_ops)
412
413
414Operation Representation
415~~~~~~~~~~~~~~~~~~~~~~~~
416
417An Crypto operation is represented by an rte_crypto_op structure, which is a
418generic metadata container for all necessary information required for the
419Crypto operation to be processed on a particular Crypto device poll mode driver.
420
421.. figure:: img/crypto_op.*
422
423The operation structure includes the operation type, the operation status
424and the session type (session-based/less), a reference to the operation
425specific data, which can vary in size and content depending on the operation
426being provisioned. It also contains the source mempool for the operation,
427if it allocated from a mempool.
428
429If Crypto operations are allocated from a Crypto operation mempool, see next
430section, there is also the ability to allocate private memory with the
431operation for applications purposes.
432
433Application software is responsible for specifying all the operation specific
434fields in the ``rte_crypto_op`` structure which are then used by the Crypto PMD
435to process the requested operation.
436
437
438Operation Management and Allocation
439~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
440
441The cryptodev library provides an API set for managing Crypto operations which
442utilize the Mempool Library to allocate operation buffers. Therefore, it ensures
443that the crypto operation is interleaved optimally across the channels and
444ranks for optimal processing.
445A ``rte_crypto_op`` contains a field indicating the pool that it originated from.
446When calling ``rte_crypto_op_free(op)``, the operation returns to its original pool.
447
448.. code-block:: c
449
450   extern struct rte_mempool *
451   rte_crypto_op_pool_create(const char *name, enum rte_crypto_op_type type,
452                             unsigned nb_elts, unsigned cache_size, uint16_t priv_size,
453                             int socket_id);
454
455During pool creation ``rte_crypto_op_init()`` is called as a constructor to
456initialize each Crypto operation which subsequently calls
457``__rte_crypto_op_reset()`` to configure any operation type specific fields based
458on the type parameter.
459
460
461``rte_crypto_op_alloc()`` and ``rte_crypto_op_bulk_alloc()`` are used to allocate
462Crypto operations of a specific type from a given Crypto operation mempool.
463``__rte_crypto_op_reset()`` is called on each operation before being returned to
464allocate to a user so the operation is always in a good known state before use
465by the application.
466
467.. code-block:: c
468
469   struct rte_crypto_op *rte_crypto_op_alloc(struct rte_mempool *mempool,
470                                             enum rte_crypto_op_type type)
471
472   unsigned rte_crypto_op_bulk_alloc(struct rte_mempool *mempool,
473                                     enum rte_crypto_op_type type,
474                                     struct rte_crypto_op **ops, uint16_t nb_ops)
475
476``rte_crypto_op_free()`` is called by the application to return an operation to
477its allocating pool.
478
479.. code-block:: c
480
481   void rte_crypto_op_free(struct rte_crypto_op *op)
482
483
484Symmetric Cryptography Support
485------------------------------
486
487The cryptodev library currently provides support for the following symmetric
488Crypto operations; cipher, authentication, including chaining of these
489operations, as well as also supporting AEAD operations.
490
491
492Session and Session Management
493~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
494
495Sessions are used in symmetric cryptographic processing to store the immutable
496data defined in a cryptographic transform which is used in the operation
497processing of a packet flow. Sessions are used to manage information such as
498expand cipher keys and HMAC IPADs and OPADs, which need to be calculated for a
499particular Crypto operation, but are immutable on a packet to packet basis for
500a flow. Crypto sessions cache this immutable data in a optimal way for the
501underlying PMD and this allows further acceleration of the offload of
502Crypto workloads.
503
504.. figure:: img/cryptodev_sym_sess.*
505
506The Crypto device framework provides APIs to create session mempool and allocate
507and initialize sessions for crypto devices, where sessions are mempool objects.
508The application has to use ``rte_cryptodev_sym_session_pool_create()`` to
509create the session header mempool that creates a mempool with proper element
510size automatically and stores necessary information for safely accessing the
511session in the mempool's private data field.
512
513To create a mempool for storing session private data, the application has two
514options. The first is to create another mempool with elt size equal to or
515bigger than the maximum session private data size of all crypto devices that
516will share the same session header. The creation of the mempool shall use the
517traditional ``rte_mempool_create()`` with the correct ``elt_size``. The other
518option is to change the ``elt_size`` parameter in
519``rte_cryptodev_sym_session_pool_create()`` to the correct value. The first
520option is more complex to implement but may result in better memory usage as
521a session header normally takes smaller memory footprint as the session private
522data.
523
524Once the session mempools have been created, ``rte_cryptodev_sym_session_create()``
525is used to allocate an uninitialized session from the given mempool.
526The session then must be initialized using ``rte_cryptodev_sym_session_init()``
527for each of the required crypto devices. A symmetric transform chain
528is used to specify the operation and its parameters. See the section below for
529details on transforms.
530
531When a session is no longer used, user must call ``rte_cryptodev_sym_session_clear()``
532for each of the crypto devices that are using the session, to free all driver
533private session data. Once this is done, session should be freed using
534``rte_cryptodev_sym_session_free`` which returns them to their mempool.
535
536
537Transforms and Transform Chaining
538~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
539
540Symmetric Crypto transforms (``rte_crypto_sym_xform``) are the mechanism used
541to specify the details of the Crypto operation. For chaining of symmetric
542operations such as cipher encrypt and authentication generate, the next pointer
543allows transform to be chained together. Crypto devices which support chaining
544must publish the chaining of symmetric Crypto operations feature flag. Allocation of the
545xform structure is in the application domain. To allow future API extensions in a
546backwardly compatible manner, e.g. addition of a new parameter, the application should
547zero the full xform struct before populating it.
548
549Currently there are three transforms types cipher, authentication and AEAD.
550Also it is important to note that the order in which the
551transforms are passed indicates the order of the chaining.
552
553.. code-block:: c
554
555    struct rte_crypto_sym_xform {
556        struct rte_crypto_sym_xform *next;
557        /**< next xform in chain */
558        enum rte_crypto_sym_xform_type type;
559        /**< xform type */
560        union {
561            struct rte_crypto_auth_xform auth;
562            /**< Authentication / hash xform */
563            struct rte_crypto_cipher_xform cipher;
564            /**< Cipher xform */
565            struct rte_crypto_aead_xform aead;
566            /**< AEAD xform */
567        };
568    };
569
570The API does not place a limit on the number of transforms that can be chained
571together but this will be limited by the underlying Crypto device poll mode
572driver which is processing the operation.
573
574.. figure:: img/crypto_xform_chain.*
575
576
577Symmetric Operations
578~~~~~~~~~~~~~~~~~~~~
579
580The symmetric Crypto operation structure contains all the mutable data relating
581to performing symmetric cryptographic processing on a referenced mbuf data
582buffer. It is used for either cipher, authentication, AEAD and chained
583operations.
584
585As a minimum the symmetric operation must have a source data buffer (``m_src``),
586a valid session (or transform chain if in session-less mode) and the minimum
587authentication/ cipher/ AEAD parameters required depending on the type of operation
588specified in the session or the transform
589chain.
590
591.. code-block:: c
592
593    struct rte_crypto_sym_op {
594        struct rte_mbuf *m_src;
595        struct rte_mbuf *m_dst;
596
597        union {
598            struct rte_cryptodev_sym_session *session;
599            /**< Handle for the initialised session context */
600            struct rte_crypto_sym_xform *xform;
601            /**< Session-less API Crypto operation parameters */
602        };
603
604        union {
605            struct {
606                struct {
607                    uint32_t offset;
608                    uint32_t length;
609                } data; /**< Data offsets and length for AEAD */
610
611                struct {
612                    uint8_t *data;
613                    rte_iova_t phys_addr;
614                } digest; /**< Digest parameters */
615
616                struct {
617                    uint8_t *data;
618                    rte_iova_t phys_addr;
619                } aad;
620                /**< Additional authentication parameters */
621            } aead;
622
623            struct {
624                struct {
625                    struct {
626                        uint32_t offset;
627                        uint32_t length;
628                    } data; /**< Data offsets and length for ciphering */
629                } cipher;
630
631                struct {
632                    struct {
633                        uint32_t offset;
634                        uint32_t length;
635                    } data;
636                    /**< Data offsets and length for authentication */
637
638                    struct {
639                        uint8_t *data;
640                        rte_iova_t phys_addr;
641                    } digest; /**< Digest parameters */
642                } auth;
643            };
644        };
645    };
646
647Synchronous mode
648----------------
649
650Some cryptodevs support synchronous mode alongside with a standard asynchronous
651mode. In that case operations are performed directly when calling
652``rte_cryptodev_sym_cpu_crypto_process`` method instead of enqueuing and
653dequeuing an operation before. This mode of operation allows cryptodevs which
654utilize CPU cryptographic acceleration to have significant performance boost
655comparing to standard asynchronous approach. Cryptodevs supporting synchronous
656mode have ``RTE_CRYPTODEV_FF_SYM_CPU_CRYPTO`` feature flag set.
657
658To perform a synchronous operation a call to
659``rte_cryptodev_sym_cpu_crypto_process`` has to be made with vectorized
660operation descriptor (``struct rte_crypto_sym_vec``) containing:
661
662- ``num`` - number of operations to perform,
663- pointer to an array of size ``num`` containing a scatter-gather list
664  descriptors of performed operations (``struct rte_crypto_sgl``). Each instance
665  of ``struct rte_crypto_sgl`` consists of a number of segments and a pointer to
666  an array of segment descriptors ``struct rte_crypto_vec``;
667- pointers to arrays of size ``num`` containing IV, AAD and digest information
668  in the ``cpu_crypto`` sub-structure,
669- pointer to an array of size ``num`` where status information will be stored
670  for each operation.
671
672Function returns a number of successfully completed operations and sets
673appropriate status number for each operation in the status array provided as
674a call argument. Status different than zero must be treated as error.
675
676For more details, e.g. how to convert an mbuf to an SGL, please refer to an
677example usage in the IPsec library implementation.
678
679Cryptodev Raw Data-path APIs
680~~~~~~~~~~~~~~~~~~~~~~~~~~~~
681
682The Crypto Raw data-path APIs are a set of APIs designed to enable external
683libraries/applications to leverage the cryptographic processing provided by
684DPDK crypto PMDs through the cryptodev API but in a manner that is not
685dependent on native DPDK data structures (eg. rte_mbuf, rte_crypto_op, ... etc)
686in their data-path implementation.
687
688The raw data-path APIs have the following advantages:
689
690- External data structure friendly design. The new APIs uses the operation
691  descriptor ``struct rte_crypto_sym_vec`` that supports raw data pointer and
692  IOVA addresses as input. Moreover, the APIs does not require the user to
693  allocate the descriptor from mempool, nor requiring mbufs to describe input
694  data's virtual and IOVA addresses. All these features made the translation
695  from user's own data structure into the descriptor easier and more efficient.
696
697- Flexible enqueue and dequeue operation. The raw data-path APIs gives the
698  user more control to the enqueue and dequeue operations, including the
699  capability of precious enqueue/dequeue count, abandoning enqueue or dequeue
700  at any time, and operation status translation and set on the fly.
701
702Cryptodev PMDs which support the raw data-path APIs will have
703``RTE_CRYPTODEV_FF_SYM_RAW_DP`` feature flag presented. To use this feature,
704the user shall create a local ``struct rte_crypto_raw_dp_ctx`` buffer and
705extend to at least the length returned by ``rte_cryptodev_get_raw_dp_ctx_size``
706function call. The created buffer is then initialized using
707``rte_cryptodev_configure_raw_dp_ctx`` function with the ``is_update``
708parameter as 0. The library and the crypto device driver will then set the
709buffer and attach either the cryptodev sym session, the rte_security session,
710or the cryptodev xform for session-less operation into the ctx buffer, and
711set the corresponding enqueue and dequeue function handlers based on the
712algorithm information stored in the session or xform. When the ``is_update``
713parameter passed into ``rte_cryptodev_configure_raw_dp_ctx`` is 1, the driver
714will not initialize the buffer but only update the session or xform and
715the function handlers accordingly.
716
717After the ``struct rte_crypto_raw_dp_ctx`` buffer is initialized, it is now
718ready for enqueue and dequeue operation. There are two different enqueue
719functions: ``rte_cryptodev_raw_enqueue`` to enqueue single raw data
720operation, and ``rte_cryptodev_raw_enqueue_burst`` to enqueue a descriptor
721with multiple operations. In case of the application uses similar approach to
722``struct rte_crypto_sym_vec`` to manage its data burst but with different
723data structure, using the ``rte_cryptodev_raw_enqueue_burst`` function may be
724less efficient as this is a situation where the application has to loop over
725all crypto operations to assemble the ``struct rte_crypto_sym_vec`` descriptor
726from its own data structure, and then the driver will loop over them again to
727translate every operation in the descriptor to the driver's specific queue data.
728The ``rte_cryptodev_raw_enqueue`` should be used to save one loop for each data
729burst instead.
730
731The ``rte_cryptodev_raw_enqueue`` and ``rte_cryptodev_raw_enqueue_burst``
732functions will return or set the enqueue status. ``rte_cryptodev_raw_enqueue``
733will return the status directly, ``rte_cryptodev_raw_enqueue_burst`` will
734return the number of operations enqueued or stored (explained as follows) and
735set the ``enqueue_status`` buffer provided by the user. The possible
736enqueue status values are:
737
738- ``1``: the operation(s) is/are enqueued successfully.
739- ``0``: the operation(s) is/are cached successfully in the crypto device queue
740  but is not actually enqueued. The user shall call
741  ``rte_cryptodev_raw_enqueue_done`` function after the expected operations
742  are stored. The crypto device will then start enqueuing all of them at
743  once.
744- The negative integer: error occurred during enqueue.
745
746Calling ``rte_cryptodev_configure_raw_dp_ctx`` with the parameter ``is_update``
747set as 0 twice without the enqueue function returning or setting enqueue status
748to 1 or ``rte_cryptodev_raw_enqueue_done`` function being called in between will
749invalidate any operation stored in the device queue but not enqueued. This
750feature is useful when the user wants to abandon partially enqueued operations
751for a failed enqueue burst operation and try enqueuing in a whole later.
752
753Similar as enqueue, there are two dequeue functions:
754``rte_cryptodev_raw_dequeue`` for dequeuing single operation, and
755``rte_cryptodev_raw_dequeue_burst`` for dequeuing a burst of operations (e.g.
756all operations in a ``struct rte_crypto_sym_vec`` descriptor). The
757``rte_cryptodev_raw_dequeue_burst`` function allows the user to provide callback
758functions to retrieve dequeue count from the enqueued user data and write the
759expected status value to the user data on the fly. The dequeue functions also
760set the dequeue status:
761
762- ``1``: the operation(s) is/are dequeued successfully.
763- ``0``: the operation(s) is/are completed but is not actually dequeued (hence
764  still kept in the device queue). The user shall call the
765  ``rte_cryptodev_raw_dequeue_done`` function after the expected number of
766  operations (e.g. all operations in a descriptor) are dequeued. The crypto
767  device driver will then free them from the queue at once.
768- The negative integer: error occurred during dequeue.
769
770Calling ``rte_cryptodev_configure_raw_dp_ctx`` with the parameter ``is_update``
771set as 0 twice without the dequeue functions execution changed dequeue_status
772to 1 or ``rte_cryptodev_raw_dequeue_done`` function being called in between will
773revert the crypto device queue's dequeue effort to the moment when the
774``struct rte_crypto_raw_dp_ctx`` buffer is initialized. This feature is useful
775when the user wants to abandon partially dequeued data and try dequeuing again
776later in a whole.
777
778There are a few limitations to the raw data path APIs:
779
780* Only support in-place operations.
781* APIs are NOT thread-safe.
782* CANNOT mix the raw data-path API's enqueue with rte_cryptodev_enqueue_burst,
783  or vice versa.
784
785See *DPDK API Reference* for details on each API definitions.
786
787Sample code
788-----------
789
790There are various sample applications that show how to use the cryptodev library,
791such as the L2fwd with Crypto sample application (L2fwd-crypto) and
792the IPsec Security Gateway application (ipsec-secgw).
793
794While these applications demonstrate how an application can be created to perform
795generic crypto operation, the required complexity hides the basic steps of
796how to use the cryptodev APIs.
797
798The following sample code shows the basic steps to encrypt several buffers
799with AES-CBC (although performing other crypto operations is similar),
800using one of the crypto PMDs available in DPDK.
801
802.. code-block:: c
803
804    /*
805     * Simple example to encrypt several buffers with AES-CBC using
806     * the Cryptodev APIs.
807     */
808
809    #define MAX_SESSIONS         1024
810    #define NUM_MBUFS            1024
811    #define POOL_CACHE_SIZE      128
812    #define BURST_SIZE           32
813    #define BUFFER_SIZE          1024
814    #define AES_CBC_IV_LENGTH    16
815    #define AES_CBC_KEY_LENGTH   16
816    #define IV_OFFSET            (sizeof(struct rte_crypto_op) + \
817                                 sizeof(struct rte_crypto_sym_op))
818
819    struct rte_mempool *mbuf_pool, *crypto_op_pool;
820    struct rte_mempool *session_pool, *session_priv_pool;
821    unsigned int session_size;
822    int ret;
823
824    /* Initialize EAL. */
825    ret = rte_eal_init(argc, argv);
826    if (ret < 0)
827        rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n");
828
829    uint8_t socket_id = rte_socket_id();
830
831    /* Create the mbuf pool. */
832    mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool",
833                                    NUM_MBUFS,
834                                    POOL_CACHE_SIZE,
835                                    0,
836                                    RTE_MBUF_DEFAULT_BUF_SIZE,
837                                    socket_id);
838    if (mbuf_pool == NULL)
839        rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
840
841    /*
842     * The IV is always placed after the crypto operation,
843     * so some private data is required to be reserved.
844     */
845    unsigned int crypto_op_private_data = AES_CBC_IV_LENGTH;
846
847    /* Create crypto operation pool. */
848    crypto_op_pool = rte_crypto_op_pool_create("crypto_op_pool",
849                                            RTE_CRYPTO_OP_TYPE_SYMMETRIC,
850                                            NUM_MBUFS,
851                                            POOL_CACHE_SIZE,
852                                            crypto_op_private_data,
853                                            socket_id);
854    if (crypto_op_pool == NULL)
855        rte_exit(EXIT_FAILURE, "Cannot create crypto op pool\n");
856
857    /* Create the virtual crypto device. */
858    char args[128];
859    const char *crypto_name = "crypto_aesni_mb0";
860    snprintf(args, sizeof(args), "socket_id=%d", socket_id);
861    ret = rte_vdev_init(crypto_name, args);
862    if (ret != 0)
863        rte_exit(EXIT_FAILURE, "Cannot create virtual device");
864
865    uint8_t cdev_id = rte_cryptodev_get_dev_id(crypto_name);
866
867    /* Get private session data size. */
868    session_size = rte_cryptodev_sym_get_private_session_size(cdev_id);
869
870    #ifdef USE_TWO_MEMPOOLS
871    /* Create session mempool for the session header. */
872    session_pool = rte_cryptodev_sym_session_pool_create("session_pool",
873                                    MAX_SESSIONS,
874                                    0,
875                                    POOL_CACHE_SIZE,
876                                    0,
877                                    socket_id);
878
879    /*
880     * Create session private data mempool for the
881     * private session data for the crypto device.
882     */
883    session_priv_pool = rte_mempool_create("session_pool",
884                                    MAX_SESSIONS,
885                                    session_size,
886                                    POOL_CACHE_SIZE,
887                                    0, NULL, NULL, NULL,
888                                    NULL, socket_id,
889                                    0);
890
891    #else
892    /* Use of the same mempool for session header and private data */
893	session_pool = rte_cryptodev_sym_session_pool_create("session_pool",
894                                    MAX_SESSIONS * 2,
895                                    session_size,
896                                    POOL_CACHE_SIZE,
897                                    0,
898                                    socket_id);
899
900	session_priv_pool = session_pool;
901
902    #endif
903
904    /* Configure the crypto device. */
905    struct rte_cryptodev_config conf = {
906        .nb_queue_pairs = 1,
907        .socket_id = socket_id
908    };
909
910    struct rte_cryptodev_qp_conf qp_conf = {
911        .nb_descriptors = 2048,
912        .mp_session = session_pool,
913        .mp_session_private = session_priv_pool
914    };
915
916    if (rte_cryptodev_configure(cdev_id, &conf) < 0)
917        rte_exit(EXIT_FAILURE, "Failed to configure cryptodev %u", cdev_id);
918
919    if (rte_cryptodev_queue_pair_setup(cdev_id, 0, &qp_conf, socket_id) < 0)
920        rte_exit(EXIT_FAILURE, "Failed to setup queue pair\n");
921
922    if (rte_cryptodev_start(cdev_id) < 0)
923        rte_exit(EXIT_FAILURE, "Failed to start device\n");
924
925    /* Create the crypto transform. */
926    uint8_t cipher_key[16] = {0};
927    struct rte_crypto_sym_xform cipher_xform = {
928        .next = NULL,
929        .type = RTE_CRYPTO_SYM_XFORM_CIPHER,
930        .cipher = {
931            .op = RTE_CRYPTO_CIPHER_OP_ENCRYPT,
932            .algo = RTE_CRYPTO_CIPHER_AES_CBC,
933            .key = {
934                .data = cipher_key,
935                .length = AES_CBC_KEY_LENGTH
936            },
937            .iv = {
938                .offset = IV_OFFSET,
939                .length = AES_CBC_IV_LENGTH
940            }
941        }
942    };
943
944    /* Create crypto session and initialize it for the crypto device. */
945    struct rte_cryptodev_sym_session *session;
946    session = rte_cryptodev_sym_session_create(session_pool);
947    if (session == NULL)
948        rte_exit(EXIT_FAILURE, "Session could not be created\n");
949
950    if (rte_cryptodev_sym_session_init(cdev_id, session,
951                    &cipher_xform, session_priv_pool) < 0)
952        rte_exit(EXIT_FAILURE, "Session could not be initialized "
953                    "for the crypto device\n");
954
955    /* Get a burst of crypto operations. */
956    struct rte_crypto_op *crypto_ops[BURST_SIZE];
957    if (rte_crypto_op_bulk_alloc(crypto_op_pool,
958                            RTE_CRYPTO_OP_TYPE_SYMMETRIC,
959                            crypto_ops, BURST_SIZE) == 0)
960        rte_exit(EXIT_FAILURE, "Not enough crypto operations available\n");
961
962    /* Get a burst of mbufs. */
963    struct rte_mbuf *mbufs[BURST_SIZE];
964    if (rte_pktmbuf_alloc_bulk(mbuf_pool, mbufs, BURST_SIZE) < 0)
965        rte_exit(EXIT_FAILURE, "Not enough mbufs available");
966
967    /* Initialize the mbufs and append them to the crypto operations. */
968    unsigned int i;
969    for (i = 0; i < BURST_SIZE; i++) {
970        if (rte_pktmbuf_append(mbufs[i], BUFFER_SIZE) == NULL)
971            rte_exit(EXIT_FAILURE, "Not enough room in the mbuf\n");
972        crypto_ops[i]->sym->m_src = mbufs[i];
973    }
974
975    /* Set up the crypto operations. */
976    for (i = 0; i < BURST_SIZE; i++) {
977        struct rte_crypto_op *op = crypto_ops[i];
978        /* Modify bytes of the IV at the end of the crypto operation */
979        uint8_t *iv_ptr = rte_crypto_op_ctod_offset(op, uint8_t *,
980                                                IV_OFFSET);
981
982        generate_random_bytes(iv_ptr, AES_CBC_IV_LENGTH);
983
984        op->sym->cipher.data.offset = 0;
985        op->sym->cipher.data.length = BUFFER_SIZE;
986
987        /* Attach the crypto session to the operation */
988        rte_crypto_op_attach_sym_session(op, session);
989    }
990
991    /* Enqueue the crypto operations in the crypto device. */
992    uint16_t num_enqueued_ops = rte_cryptodev_enqueue_burst(cdev_id, 0,
993                                            crypto_ops, BURST_SIZE);
994
995    /*
996     * Dequeue the crypto operations until all the operations
997     * are processed in the crypto device.
998     */
999    uint16_t num_dequeued_ops, total_num_dequeued_ops = 0;
1000    do {
1001        struct rte_crypto_op *dequeued_ops[BURST_SIZE];
1002        num_dequeued_ops = rte_cryptodev_dequeue_burst(cdev_id, 0,
1003                                        dequeued_ops, BURST_SIZE);
1004        total_num_dequeued_ops += num_dequeued_ops;
1005
1006        /* Check if operation was processed successfully */
1007        for (i = 0; i < num_dequeued_ops; i++) {
1008            if (dequeued_ops[i]->status != RTE_CRYPTO_OP_STATUS_SUCCESS)
1009                rte_exit(EXIT_FAILURE,
1010                        "Some operations were not processed correctly");
1011        }
1012
1013        rte_mempool_put_bulk(crypto_op_pool, (void **)dequeued_ops,
1014                                            num_dequeued_ops);
1015    } while (total_num_dequeued_ops < num_enqueued_ops);
1016
1017Asymmetric Cryptography
1018-----------------------
1019
1020The cryptodev library currently provides support for the following asymmetric
1021Crypto operations; RSA, Modular exponentiation and inversion, Diffie-Hellman and
1022Elliptic Curve Diffie-Hellman public and/or private key generation and shared
1023secret compute, DSA Signature generation and verification.
1024
1025Session and Session Management
1026~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1027
1028Sessions are used in asymmetric cryptographic processing to store the immutable
1029data defined in asymmetric cryptographic transform which is further used in the
1030operation processing. Sessions typically stores information, such as, public
1031and private key information or domain params or prime modulus data i.e. immutable
1032across data sets. Crypto sessions cache this immutable data in a optimal way for the
1033underlying PMD and this allows further acceleration of the offload of Crypto workloads.
1034
1035Like symmetric, the Crypto device framework provides APIs to allocate and initialize
1036asymmetric sessions for crypto devices, where sessions are mempool objects.
1037It is the application's responsibility to create and manage the session mempools.
1038Application using both symmetric and asymmetric sessions should allocate and maintain
1039different sessions pools for each type.
1040
1041An application can use ``rte_cryptodev_asym_session_pool_create()`` to create a mempool
1042with a specified number of elements. The element size will allow for the session header,
1043and the max private session size.
1044The max private session size is chosen based on available crypto devices,
1045the biggest private session size is used. This means any of those devices can be used,
1046and the mempool element will have available space for its private session data.
1047
1048Once the session mempools have been created, ``rte_cryptodev_asym_session_create()``
1049is used to allocate and initialize an asymmetric session from the given mempool.
1050An asymmetric transform chain is used to specify the operation and its parameters.
1051See the section below for details on transforms.
1052
1053When a session is no longer used, user must call ``rte_cryptodev_asym_session_clear()``
1054for each of the crypto devices that are using the session, to free all driver
1055private asymmetric session data. Once this is done, session should be freed using
1056``rte_cryptodev_asym_session_free()`` which returns them to their mempool.
1057
1058Asymmetric Sessionless Support
1059~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1060
1061Asymmetric crypto framework supports session-less operations as well.
1062
1063Fields that should be set by user are:
1064
1065Member xform of struct rte_crypto_asym_op should point to the user created rte_crypto_asym_xform.
1066Note that rte_crypto_asym_xform should be immutable for the lifetime of associated crypto_op.
1067
1068Member sess_type of rte_crypto_op should also be set to RTE_CRYPTO_OP_SESSIONLESS.
1069
1070Transforms and Transform Chaining
1071~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1072
1073Asymmetric Crypto transforms (``rte_crypto_asym_xform``) are the mechanism used
1074to specify the details of the asymmetric Crypto operation. Next pointer within
1075xform allows transform to be chained together. Also it is important to note that
1076the order in which the transforms are passed indicates the order of the chaining. Allocation
1077of the xform structure is in the application domain. To allow future API extensions in a
1078backwardly compatible manner, e.g. addition of a new parameter, the application should
1079zero the full xform struct before populating it.
1080
1081Not all asymmetric crypto xforms are supported for chaining. Currently supported
1082asymmetric crypto chaining is Diffie-Hellman private key generation followed by
1083public generation. Also, currently API does not support chaining of symmetric and
1084asymmetric crypto xforms.
1085
1086Each xform defines specific asymmetric crypto algo. Currently supported are:
1087* RSA
1088* Modular operations (Exponentiation and Inverse)
1089* Diffie-Hellman
1090* DSA
1091* Elliptic Curve Diffie-Hellman
1092* None - special case where PMD may support a passthrough mode. More for diagnostic purpose
1093
1094See *DPDK API Reference* for details on each rte_crypto_xxx_xform struct
1095
1096Asymmetric Operations
1097~~~~~~~~~~~~~~~~~~~~~
1098
1099The asymmetric Crypto operation structure contains all the mutable data relating
1100to asymmetric cryptographic processing on an input data buffer. It uses either
1101RSA, Modular, Diffie-Hellman or DSA operations depending upon session it is attached
1102to.
1103
1104Every operation must carry a valid session handle which further carries information
1105on xform or xform-chain to be performed on op. Every xform type defines its own set
1106of operational params in their respective rte_crypto_xxx_op_param struct. Depending
1107on xform information within session, PMD picks up and process respective op_param
1108struct.
1109Unlike symmetric, asymmetric operations do not use mbufs for input/output.
1110They operate on data buffer of type ``rte_crypto_param``.
1111
1112See *DPDK API Reference* for details on each rte_crypto_xxx_op_param struct
1113
1114Private user data
1115~~~~~~~~~~~~~~~~~
1116
1117Similar to symmetric above, asymmetric also has a set and get API that provides a
1118mechanism for an application to store and retrieve the private user data information
1119stored along with the crypto session.
1120
1121.. code-block:: c
1122
1123	int rte_cryptodev_asym_session_set_user_data(void *sess,
1124		void *data, uint16_t size);
1125
1126	void * rte_cryptodev_asym_session_get_user_data(void *sess);
1127
1128Please note the ``size`` passed to set API cannot be bigger than the predefined
1129``user_data_sz`` when creating the session mempool, otherwise the function will
1130return an error. Also when ``user_data_sz`` was defined as ``0`` when
1131creating the session mempool, the get API will always return ``NULL``.
1132
1133Asymmetric crypto Sample code
1134-----------------------------
1135
1136There's a unit test application test_cryptodev_asym.c inside unit test framework that
1137show how to setup and process asymmetric operations using cryptodev library.
1138
1139The following code samples are taken from the test application mentioned above,
1140and show basic steps to compute modular exponentiation using an openssl PMD
1141available in DPDK (performing other crypto operations is similar except change
1142to respective op and xform setup).
1143
1144.. note::
1145   The following code snippets are taken from multiple functions, so variable
1146   names may differ slightly between sections.
1147
1148Configure the virtual device, queue pairs, crypto op pool and session mempool.
1149
1150.. literalinclude:: ../../../app/test/test_cryptodev_asym.c
1151   :language: c
1152   :start-after: Device, op pool and session configuration for asymmetric crypto. 8<
1153   :end-before: >8 End of device, op pool and session configuration for asymmetric crypto section.
1154   :dedent: 1
1155
1156Create MODEX data vectors.
1157
1158.. literalinclude:: ../../../app/test/test_cryptodev_mod_test_vectors.h
1159   :language: c
1160   :start-after: MODEX data. 8<
1161   :end-before: >8 End of MODEX data.
1162
1163Setup crypto xform to do modular exponentiation using data vectors.
1164
1165.. literalinclude:: ../../../app/test/test_cryptodev_mod_test_vectors.h
1166   :language: c
1167   :start-after: MODEX vector. 8<
1168   :end-before: >8 End of MODEX vector.
1169
1170Generate crypto op, create and attach a session, then process packets.
1171
1172.. literalinclude:: ../../../app/test/test_cryptodev_asym.c
1173   :language: c
1174   :start-after: Create op, create session, and process packets. 8<
1175   :end-before: >8 End of create op, create session, and process packets section.
1176   :dedent: 1
1177
1178.. note::
1179   The ``rte_cryptodev_asym_session`` struct is hidden from the application.
1180   The ``sess`` pointer used above is a void pointer.
1181
1182
1183Asymmetric Crypto Device API
1184~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1185
1186The cryptodev Library API is described in the
1187`DPDK API Reference <https://doc.dpdk.org/api/>`_
1188
1189
1190Device Statistics
1191-----------------
1192
1193The Cryptodev library has support for displaying Crypto device information
1194through the Telemetry interface. Telemetry commands that can be used
1195are shown below.
1196
1197#. Get the list of available Crypto devices by ID::
1198
1199     --> /cryptodev/list
1200     {"/cryptodev/list": [0, 1, 2, 3]}
1201
1202#. Get general information from a Crypto device::
1203
1204     --> /cryptodev/info,0
1205     {"/cryptodev/info": {"device_name": "0000:1c:01.0_qat_sym",
1206     "max_nb_queue_pairs": 2}}
1207
1208#. Get the statistics for a particular Crypto device::
1209
1210     --> /cryptodev/stats,0
1211     {"/cryptodev/stats": {"enqueued_count": 0, "dequeued_count": 0,
1212     "enqueue_err_count": 0, "dequeue_err_count": 0}}
1213
1214#. Get the capabilities of a particular Crypto device::
1215
1216     --> /cryptodev/caps,0
1217     {"/cryptodev/caps": {"crypto_caps": [<array of serialized bytes of
1218     capabilities>], "crypto_caps_n": <number of capabilities>}}
1219
1220For more information on how to use the Telemetry interface, see
1221the :doc:`../howto/telemetry`.
1222