New upstream version 18.08
[deb_dpdk.git] / doc / guides / prog_guide / cryptodev_lib.rst
1 ..  SPDX-License-Identifier: BSD-3-Clause
2     Copyright(c) 2016-2017 Intel Corporation.
3
4 Cryptography Device Library
5 ===========================
6
7 The cryptodev library provides a Crypto device framework for management and
8 provisioning of hardware and software Crypto poll mode drivers, defining generic
9 APIs which support a number of different Crypto operations. The framework
10 currently only supports cipher, authentication, chained cipher/authentication
11 and AEAD symmetric and asymmetric Crypto operations.
12
13
14 Design Principles
15 -----------------
16
17 The cryptodev library follows the same basic principles as those used in DPDKs
18 Ethernet Device framework. The Crypto framework provides a generic Crypto device
19 framework which supports both physical (hardware) and virtual (software) Crypto
20 devices as well as a generic Crypto API which allows Crypto devices to be
21 managed and configured and supports Crypto operations to be provisioned on
22 Crypto poll mode driver.
23
24
25 Device Management
26 -----------------
27
28 Device Creation
29 ~~~~~~~~~~~~~~~
30
31 Physical Crypto devices are discovered during the PCI probe/enumeration of the
32 EAL function which is executed at DPDK initialization, based on
33 their PCI device identifier, each unique PCI BDF (bus/bridge, device,
34 function). Specific physical Crypto devices, like other physical devices in DPDK
35 can be white-listed or black-listed using the EAL command line options.
36
37 Virtual devices can be created by two mechanisms, either using the EAL command
38 line options or from within the application using an EAL API directly.
39
40 From 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 instaces sharing the same library requires unique ID.
52
53    Example: ``--vdev  'crypto_aesni_mb0' --vdev  'crypto_aesni_mb1'``
54
55 Our 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
62 All 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
68 Device Identification
69 ~~~~~~~~~~~~~~~~~~~~~
70
71 Each device, whether virtual or physical is uniquely designated by two
72 identifiers:
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
82 Device Configuration
83 ~~~~~~~~~~~~~~~~~~~~
84
85 The 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
91 The 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
98 The ``rte_cryptodev_config`` structure is used to pass the configuration
99 parameters 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
111 Configuration of Queue Pairs
112 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
113
114 Each Crypto devices queue pair is individually configured through the
115 ``rte_cryptodev_queue_pair_setup`` API.
116 Each 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     };
127
128
129 Logical Cores, Memory and Queues Pair Relationships
130 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
131
132 The Crypto device Library as the Poll Mode Driver library support NUMA for when
133 a processor’s logical cores and interfaces utilize its local memory. Therefore
134 Crypto operations, and in the case of symmetric Crypto operations, the session
135 and the mbuf being operated on, should be allocated from memory pools created
136 in the local memory. The buffers should, if possible, remain on the local
137 processor to obtain the best performance results and buffer descriptors should
138 be populated with mbufs allocated from a mempool allocated from local memory.
139
140 The run-to-completion model also performs better, especially in the case of
141 virtual Crypto devices, if the Crypto operation and session and data buffer is
142 in local memory instead of a remote processor's memory. This is also true for
143 the pipe-line model provided all logical cores used are located on the same
144 processor.
145
146 Multiple logical cores should never share the same queue pair for enqueuing
147 operations or dequeuing operations on the same Crypto device since this would
148 require global locks and hinder performance. It is however possible to use a
149 different logical core to dequeue an operation on a queue pair from the logical
150 core which it was enqueued on. This means that a crypto burst enqueue/dequeue
151 APIs are a logical place to transition from one logical core to another in a
152 packet processing pipeline.
153
154
155 Device Features and Capabilities
156 ---------------------------------
157
158 Crypto devices define their functionality through two mechanisms, global device
159 features and algorithm capabilities. Global devices features identify device
160 wide level features which are applicable to the whole device such as
161 the device having hardware acceleration or supporting symmetric and/or asymmetric
162 Crypto operations.
163
164 The capabilities mechanism defines the individual algorithms/functions which
165 the device supports, such as a specific symmetric Crypto cipher,
166 authentication operation or Authenticated Encryption with Associated Data
167 (AEAD) operation.
168
169
170 Device Features
171 ~~~~~~~~~~~~~~~
172
173 Currently the following Crypto device features are defined:
174
175 * Symmetric Crypto operations
176 * Asymmetric Crypto operations
177 * Chaining of symmetric Crypto operations
178 * SSE accelerated SIMD vector operations
179 * AVX accelerated SIMD vector operations
180 * AVX2 accelerated SIMD vector operations
181 * AESNI accelerated instructions
182 * Hardware off-load processing
183
184
185 Device Operation Capabilities
186 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
187
188 Crypto capabilities which identify particular algorithm which the Crypto PMD
189 supports are  defined by the operation type, the operation transform, the
190 transform identifier and then the particulars of the transform. For the full
191 scope of the Crypto capability see the definition of the structure in the
192 *DPDK API Reference*.
193
194 .. code-block:: c
195
196    struct rte_cryptodev_capabilities;
197
198 Each Crypto poll mode driver defines its own private array of capabilities
199 for the operations it supports. Below is an example of the capabilities for a
200 PMD which supports the authentication algorithm SHA1_HMAC and the cipher
201 algorithm AES_CBC.
202
203 .. code-block:: c
204
205     static const struct rte_cryptodev_capabilities pmd_capabilities[] = {
206         {    /* SHA1 HMAC */
207             .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
208             .sym = {
209                 .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
210                 .auth = {
211                     .algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
212                     .block_size = 64,
213                     .key_size = {
214                         .min = 64,
215                         .max = 64,
216                         .increment = 0
217                     },
218                     .digest_size = {
219                         .min = 12,
220                         .max = 12,
221                         .increment = 0
222                     },
223                     .aad_size = { 0 },
224                     .iv_size = { 0 }
225                 }
226             }
227         },
228         {    /* AES CBC */
229             .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
230             .sym = {
231                 .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
232                 .cipher = {
233                     .algo = RTE_CRYPTO_CIPHER_AES_CBC,
234                     .block_size = 16,
235                     .key_size = {
236                         .min = 16,
237                         .max = 32,
238                         .increment = 8
239                     },
240                     .iv_size = {
241                         .min = 16,
242                         .max = 16,
243                         .increment = 0
244                     }
245                 }
246             }
247         }
248     }
249
250
251 Capabilities Discovery
252 ~~~~~~~~~~~~~~~~~~~~~~
253
254 Discovering the features and capabilities of a Crypto device poll mode driver
255 is achieved through the ``rte_cryptodev_info_get`` function.
256
257 .. code-block:: c
258
259    void rte_cryptodev_info_get(uint8_t dev_id,
260                                struct rte_cryptodev_info *dev_info);
261
262 This allows the user to query a specific Crypto PMD and get all the device
263 features and capabilities. The ``rte_cryptodev_info`` structure contains all the
264 relevant information for the device.
265
266 .. code-block:: c
267
268     struct rte_cryptodev_info {
269         const char *driver_name;
270         uint8_t driver_id;
271         struct rte_device *device;
272
273         uint64_t feature_flags;
274
275         const struct rte_cryptodev_capabilities *capabilities;
276
277         unsigned max_nb_queue_pairs;
278
279         struct {
280             unsigned max_nb_sessions;
281         } sym;
282     };
283
284
285 Operation Processing
286 --------------------
287
288 Scheduling of Crypto operations on DPDK's application data path is
289 performed using a burst oriented asynchronous API set. A queue pair on a Crypto
290 device accepts a burst of Crypto operations using enqueue burst API. On physical
291 Crypto devices the enqueue burst API will place the operations to be processed
292 on the devices hardware input queue, for virtual devices the processing of the
293 Crypto operations is usually completed during the enqueue call to the Crypto
294 device. The dequeue burst API will retrieve any processed operations available
295 from the queue pair on the Crypto device, from physical devices this is usually
296 directly from the devices processed queue, and for virtual device's from a
297 ``rte_ring`` where processed operations are place after being processed on the
298 enqueue call.
299
300
301 Private data
302 ~~~~~~~~~~~~
303 For session-based operations, the set and get API provides a mechanism for an
304 application to store and retrieve the private user data information stored along
305 with the crypto session.
306
307 For example, suppose an application is submitting a crypto operation with a session
308 associated and wants to indicate private user data information which is required to be
309 used after completion of the crypto operation. In this case, the application can use
310 the set API to set the user data and retrieve it using get API.
311
312 .. code-block:: c
313
314         int rte_cryptodev_sym_session_set_user_data(
315                 struct rte_cryptodev_sym_session *sess, void *data, uint16_t size);
316
317         void * rte_cryptodev_sym_session_get_user_data(
318                 struct rte_cryptodev_sym_session *sess);
319
320
321 For session-less mode, the private user data information can be placed along with the
322 ``struct rte_crypto_op``. The ``rte_crypto_op::private_data_offset`` indicates the
323 start of private data information. The offset is counted from the start of the
324 rte_crypto_op including other crypto information such as the IVs (since there can
325 be an IV also for authentication).
326
327
328 Enqueue / Dequeue Burst APIs
329 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
330
331 The burst enqueue API uses a Crypto device identifier and a queue pair
332 identifier to specify the Crypto device queue pair to schedule the processing on.
333 The ``nb_ops`` parameter is the number of operations to process which are
334 supplied in the ``ops`` array of ``rte_crypto_op`` structures.
335 The enqueue function returns the number of operations it actually enqueued for
336 processing, a return value equal to ``nb_ops`` means that all packets have been
337 enqueued.
338
339 .. code-block:: c
340
341    uint16_t rte_cryptodev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
342                                         struct rte_crypto_op **ops, uint16_t nb_ops)
343
344 The dequeue API uses the same format as the enqueue API of processed but
345 the ``nb_ops`` and ``ops`` parameters are now used to specify the max processed
346 operations the user wishes to retrieve and the location in which to store them.
347 The API call returns the actual number of processed operations returned, this
348 can never be larger than ``nb_ops``.
349
350 .. code-block:: c
351
352    uint16_t rte_cryptodev_dequeue_burst(uint8_t dev_id, uint16_t qp_id,
353                                         struct rte_crypto_op **ops, uint16_t nb_ops)
354
355
356 Operation Representation
357 ~~~~~~~~~~~~~~~~~~~~~~~~
358
359 An Crypto operation is represented by an rte_crypto_op structure, which is a
360 generic metadata container for all necessary information required for the
361 Crypto operation to be processed on a particular Crypto device poll mode driver.
362
363 .. figure:: img/crypto_op.*
364
365 The operation structure includes the operation type, the operation status
366 and the session type (session-based/less), a reference to the operation
367 specific data, which can vary in size and content depending on the operation
368 being provisioned. It also contains the source mempool for the operation,
369 if it allocated from a mempool.
370
371 If Crypto operations are allocated from a Crypto operation mempool, see next
372 section, there is also the ability to allocate private memory with the
373 operation for applications purposes.
374
375 Application software is responsible for specifying all the operation specific
376 fields in the ``rte_crypto_op`` structure which are then used by the Crypto PMD
377 to process the requested operation.
378
379
380 Operation Management and Allocation
381 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
382
383 The cryptodev library provides an API set for managing Crypto operations which
384 utilize the Mempool Library to allocate operation buffers. Therefore, it ensures
385 that the crytpo operation is interleaved optimally across the channels and
386 ranks for optimal processing.
387 A ``rte_crypto_op`` contains a field indicating the pool that it originated from.
388 When calling ``rte_crypto_op_free(op)``, the operation returns to its original pool.
389
390 .. code-block:: c
391
392    extern struct rte_mempool *
393    rte_crypto_op_pool_create(const char *name, enum rte_crypto_op_type type,
394                              unsigned nb_elts, unsigned cache_size, uint16_t priv_size,
395                              int socket_id);
396
397 During pool creation ``rte_crypto_op_init()`` is called as a constructor to
398 initialize each Crypto operation which subsequently calls
399 ``__rte_crypto_op_reset()`` to configure any operation type specific fields based
400 on the type parameter.
401
402
403 ``rte_crypto_op_alloc()`` and ``rte_crypto_op_bulk_alloc()`` are used to allocate
404 Crypto operations of a specific type from a given Crypto operation mempool.
405 ``__rte_crypto_op_reset()`` is called on each operation before being returned to
406 allocate to a user so the operation is always in a good known state before use
407 by the application.
408
409 .. code-block:: c
410
411    struct rte_crypto_op *rte_crypto_op_alloc(struct rte_mempool *mempool,
412                                              enum rte_crypto_op_type type)
413
414    unsigned rte_crypto_op_bulk_alloc(struct rte_mempool *mempool,
415                                      enum rte_crypto_op_type type,
416                                      struct rte_crypto_op **ops, uint16_t nb_ops)
417
418 ``rte_crypto_op_free()`` is called by the application to return an operation to
419 its allocating pool.
420
421 .. code-block:: c
422
423    void rte_crypto_op_free(struct rte_crypto_op *op)
424
425
426 Symmetric Cryptography Support
427 ------------------------------
428
429 The cryptodev library currently provides support for the following symmetric
430 Crypto operations; cipher, authentication, including chaining of these
431 operations, as well as also supporting AEAD operations.
432
433
434 Session and Session Management
435 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
436
437 Sessions are used in symmetric cryptographic processing to store the immutable
438 data defined in a cryptographic transform which is used in the operation
439 processing of a packet flow. Sessions are used to manage information such as
440 expand cipher keys and HMAC IPADs and OPADs, which need to be calculated for a
441 particular Crypto operation, but are immutable on a packet to packet basis for
442 a flow. Crypto sessions cache this immutable data in a optimal way for the
443 underlying PMD and this allows further acceleration of the offload of
444 Crypto workloads.
445
446 .. figure:: img/cryptodev_sym_sess.*
447
448 The Crypto device framework provides APIs to allocate and initialize sessions
449 for crypto devices, where sessions are mempool objects.
450 It is the application's responsibility to create and manage the session mempools.
451 This approach allows for different scenarios such as having a single session
452 mempool for all crypto devices (where the mempool object size is big
453 enough to hold the private session of any crypto device), as well as having
454 multiple session mempools of different sizes for better memory usage.
455
456 An application can use ``rte_cryptodev_sym_get_private_session_size()`` to
457 get the private session size of given crypto device. This function would allow
458 an application to calculate the max device session size of all crypto devices
459 to create a single session mempool.
460 If instead an application creates multiple session mempools, the Crypto device
461 framework also provides ``rte_cryptodev_sym_get_header_session_size`` to get
462 the size of an uninitialized session.
463
464 Once the session mempools have been created, ``rte_cryptodev_sym_session_create()``
465 is used to allocate an uninitialized session from the given mempool.
466 The session then must be initialized using ``rte_cryptodev_sym_session_init()``
467 for each of the required crypto devices. A symmetric transform chain
468 is used to specify the operation and its parameters. See the section below for
469 details on transforms.
470
471 When a session is no longer used, user must call ``rte_cryptodev_sym_session_clear()``
472 for each of the crypto devices that are using the session, to free all driver
473 private session data. Once this is done, session should be freed using
474 ``rte_cryptodev_sym_session_free`` which returns them to their mempool.
475
476
477 Transforms and Transform Chaining
478 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
479
480 Symmetric Crypto transforms (``rte_crypto_sym_xform``) are the mechanism used
481 to specify the details of the Crypto operation. For chaining of symmetric
482 operations such as cipher encrypt and authentication generate, the next pointer
483 allows transform to be chained together. Crypto devices which support chaining
484 must publish the chaining of symmetric Crypto operations feature flag.
485
486 Currently there are three transforms types cipher, authentication and AEAD.
487 Also it is important to note that the order in which the
488 transforms are passed indicates the order of the chaining.
489
490 .. code-block:: c
491
492     struct rte_crypto_sym_xform {
493         struct rte_crypto_sym_xform *next;
494         /**< next xform in chain */
495         enum rte_crypto_sym_xform_type type;
496         /**< xform type */
497         union {
498             struct rte_crypto_auth_xform auth;
499             /**< Authentication / hash xform */
500             struct rte_crypto_cipher_xform cipher;
501             /**< Cipher xform */
502             struct rte_crypto_aead_xform aead;
503             /**< AEAD xform */
504         };
505     };
506
507 The API does not place a limit on the number of transforms that can be chained
508 together but this will be limited by the underlying Crypto device poll mode
509 driver which is processing the operation.
510
511 .. figure:: img/crypto_xform_chain.*
512
513
514 Symmetric Operations
515 ~~~~~~~~~~~~~~~~~~~~
516
517 The symmetric Crypto operation structure contains all the mutable data relating
518 to performing symmetric cryptographic processing on a referenced mbuf data
519 buffer. It is used for either cipher, authentication, AEAD and chained
520 operations.
521
522 As a minimum the symmetric operation must have a source data buffer (``m_src``),
523 a valid session (or transform chain if in session-less mode) and the minimum
524 authentication/ cipher/ AEAD parameters required depending on the type of operation
525 specified in the session or the transform
526 chain.
527
528 .. code-block:: c
529
530     struct rte_crypto_sym_op {
531         struct rte_mbuf *m_src;
532         struct rte_mbuf *m_dst;
533
534         union {
535             struct rte_cryptodev_sym_session *session;
536             /**< Handle for the initialised session context */
537             struct rte_crypto_sym_xform *xform;
538             /**< Session-less API Crypto operation parameters */
539         };
540
541         union {
542             struct {
543                 struct {
544                     uint32_t offset;
545                     uint32_t length;
546                 } data; /**< Data offsets and length for AEAD */
547
548                 struct {
549                     uint8_t *data;
550                     rte_iova_t phys_addr;
551                 } digest; /**< Digest parameters */
552
553                 struct {
554                     uint8_t *data;
555                     rte_iova_t phys_addr;
556                 } aad;
557                 /**< Additional authentication parameters */
558             } aead;
559
560             struct {
561                 struct {
562                     struct {
563                         uint32_t offset;
564                         uint32_t length;
565                     } data; /**< Data offsets and length for ciphering */
566                 } cipher;
567
568                 struct {
569                     struct {
570                         uint32_t offset;
571                         uint32_t length;
572                     } data;
573                     /**< Data offsets and length for authentication */
574
575                     struct {
576                         uint8_t *data;
577                         rte_iova_t phys_addr;
578                     } digest; /**< Digest parameters */
579                 } auth;
580             };
581         };
582     };
583
584 Sample code
585 -----------
586
587 There are various sample applications that show how to use the cryptodev library,
588 such as the L2fwd with Crypto sample application (L2fwd-crypto) and
589 the IPSec Security Gateway application (ipsec-secgw).
590
591 While these applications demonstrate how an application can be created to perform
592 generic crypto operation, the required complexity hides the basic steps of
593 how to use the cryptodev APIs.
594
595 The following sample code shows the basic steps to encrypt several buffers
596 with AES-CBC (although performing other crypto operations is similar),
597 using one of the crypto PMDs available in DPDK.
598
599 .. code-block:: c
600
601     /*
602      * Simple example to encrypt several buffers with AES-CBC using
603      * the Cryptodev APIs.
604      */
605
606     #define MAX_SESSIONS         1024
607     #define NUM_MBUFS            1024
608     #define POOL_CACHE_SIZE      128
609     #define BURST_SIZE           32
610     #define BUFFER_SIZE          1024
611     #define AES_CBC_IV_LENGTH    16
612     #define AES_CBC_KEY_LENGTH   16
613     #define IV_OFFSET            (sizeof(struct rte_crypto_op) + \
614                                  sizeof(struct rte_crypto_sym_op))
615
616     struct rte_mempool *mbuf_pool, *crypto_op_pool, *session_pool;
617     unsigned int session_size;
618     int ret;
619
620     /* Initialize EAL. */
621     ret = rte_eal_init(argc, argv);
622     if (ret < 0)
623         rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n");
624
625     uint8_t socket_id = rte_socket_id();
626
627     /* Create the mbuf pool. */
628     mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool",
629                                     NUM_MBUFS,
630                                     POOL_CACHE_SIZE,
631                                     0,
632                                     RTE_MBUF_DEFAULT_BUF_SIZE,
633                                     socket_id);
634     if (mbuf_pool == NULL)
635         rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
636
637     /*
638      * The IV is always placed after the crypto operation,
639      * so some private data is required to be reserved.
640      */
641     unsigned int crypto_op_private_data = AES_CBC_IV_LENGTH;
642
643     /* Create crypto operation pool. */
644     crypto_op_pool = rte_crypto_op_pool_create("crypto_op_pool",
645                                             RTE_CRYPTO_OP_TYPE_SYMMETRIC,
646                                             NUM_MBUFS,
647                                             POOL_CACHE_SIZE,
648                                             crypto_op_private_data,
649                                             socket_id);
650     if (crypto_op_pool == NULL)
651         rte_exit(EXIT_FAILURE, "Cannot create crypto op pool\n");
652
653     /* Create the virtual crypto device. */
654     char args[128];
655     const char *crypto_name = "crypto_aesni_mb0";
656     snprintf(args, sizeof(args), "socket_id=%d", socket_id);
657     ret = rte_vdev_init(crypto_name, args);
658     if (ret != 0)
659         rte_exit(EXIT_FAILURE, "Cannot create virtual device");
660
661     uint8_t cdev_id = rte_cryptodev_get_dev_id(crypto_name);
662
663     /* Get private session data size. */
664     session_size = rte_cryptodev_sym_get_private_session_size(cdev_id);
665
666     /*
667      * Create session mempool, with two objects per session,
668      * one for the session header and another one for the
669      * private session data for the crypto device.
670      */
671     session_pool = rte_mempool_create("session_pool",
672                                     MAX_SESSIONS * 2,
673                                     session_size,
674                                     POOL_CACHE_SIZE,
675                                     0, NULL, NULL, NULL,
676                                     NULL, socket_id,
677                                     0);
678
679     /* Configure the crypto device. */
680     struct rte_cryptodev_config conf = {
681         .nb_queue_pairs = 1,
682         .socket_id = socket_id
683     };
684     struct rte_cryptodev_qp_conf qp_conf = {
685         .nb_descriptors = 2048
686     };
687
688     if (rte_cryptodev_configure(cdev_id, &conf) < 0)
689         rte_exit(EXIT_FAILURE, "Failed to configure cryptodev %u", cdev_id);
690
691     if (rte_cryptodev_queue_pair_setup(cdev_id, 0, &qp_conf,
692                             socket_id, session_pool) < 0)
693         rte_exit(EXIT_FAILURE, "Failed to setup queue pair\n");
694
695     if (rte_cryptodev_start(cdev_id) < 0)
696         rte_exit(EXIT_FAILURE, "Failed to start device\n");
697
698     /* Create the crypto transform. */
699     uint8_t cipher_key[16] = {0};
700     struct rte_crypto_sym_xform cipher_xform = {
701         .next = NULL,
702         .type = RTE_CRYPTO_SYM_XFORM_CIPHER,
703         .cipher = {
704             .op = RTE_CRYPTO_CIPHER_OP_ENCRYPT,
705             .algo = RTE_CRYPTO_CIPHER_AES_CBC,
706             .key = {
707                 .data = cipher_key,
708                 .length = AES_CBC_KEY_LENGTH
709             },
710             .iv = {
711                 .offset = IV_OFFSET,
712                 .length = AES_CBC_IV_LENGTH
713             }
714         }
715     };
716
717     /* Create crypto session and initialize it for the crypto device. */
718     struct rte_cryptodev_sym_session *session;
719     session = rte_cryptodev_sym_session_create(session_pool);
720     if (session == NULL)
721         rte_exit(EXIT_FAILURE, "Session could not be created\n");
722
723     if (rte_cryptodev_sym_session_init(cdev_id, session,
724                     &cipher_xform, session_pool) < 0)
725         rte_exit(EXIT_FAILURE, "Session could not be initialized "
726                     "for the crypto device\n");
727
728     /* Get a burst of crypto operations. */
729     struct rte_crypto_op *crypto_ops[BURST_SIZE];
730     if (rte_crypto_op_bulk_alloc(crypto_op_pool,
731                             RTE_CRYPTO_OP_TYPE_SYMMETRIC,
732                             crypto_ops, BURST_SIZE) == 0)
733         rte_exit(EXIT_FAILURE, "Not enough crypto operations available\n");
734
735     /* Get a burst of mbufs. */
736     struct rte_mbuf *mbufs[BURST_SIZE];
737     if (rte_pktmbuf_alloc_bulk(mbuf_pool, mbufs, BURST_SIZE) < 0)
738         rte_exit(EXIT_FAILURE, "Not enough mbufs available");
739
740     /* Initialize the mbufs and append them to the crypto operations. */
741     unsigned int i;
742     for (i = 0; i < BURST_SIZE; i++) {
743         if (rte_pktmbuf_append(mbufs[i], BUFFER_SIZE) == NULL)
744             rte_exit(EXIT_FAILURE, "Not enough room in the mbuf\n");
745         crypto_ops[i]->sym->m_src = mbufs[i];
746     }
747
748     /* Set up the crypto operations. */
749     for (i = 0; i < BURST_SIZE; i++) {
750         struct rte_crypto_op *op = crypto_ops[i];
751         /* Modify bytes of the IV at the end of the crypto operation */
752         uint8_t *iv_ptr = rte_crypto_op_ctod_offset(op, uint8_t *,
753                                                 IV_OFFSET);
754
755         generate_random_bytes(iv_ptr, AES_CBC_IV_LENGTH);
756
757         op->sym->cipher.data.offset = 0;
758         op->sym->cipher.data.length = BUFFER_SIZE;
759
760         /* Attach the crypto session to the operation */
761         rte_crypto_op_attach_sym_session(op, session);
762     }
763
764     /* Enqueue the crypto operations in the crypto device. */
765     uint16_t num_enqueued_ops = rte_cryptodev_enqueue_burst(cdev_id, 0,
766                                             crypto_ops, BURST_SIZE);
767
768     /*
769      * Dequeue the crypto operations until all the operations
770      * are proccessed in the crypto device.
771      */
772     uint16_t num_dequeued_ops, total_num_dequeued_ops = 0;
773     do {
774         struct rte_crypto_op *dequeued_ops[BURST_SIZE];
775         num_dequeued_ops = rte_cryptodev_dequeue_burst(cdev_id, 0,
776                                         dequeued_ops, BURST_SIZE);
777         total_num_dequeued_ops += num_dequeued_ops;
778
779         /* Check if operation was processed successfully */
780         for (i = 0; i < num_dequeued_ops; i++) {
781             if (dequeued_ops[i]->status != RTE_CRYPTO_OP_STATUS_SUCCESS)
782                 rte_exit(EXIT_FAILURE,
783                         "Some operations were not processed correctly");
784         }
785
786         rte_mempool_put_bulk(crypto_op_pool, (void **)dequeued_ops,
787                                             num_dequeued_ops);
788     } while (total_num_dequeued_ops < num_enqueued_ops);
789
790 Asymmetric Cryptography
791 -----------------------
792
793 The cryptodev library currently provides support for the following asymmetric
794 Crypto operations; RSA, Modular exponentiation and inversion, Diffie-Hellman
795 public and/or private key generation and shared secret compute, DSA Signature
796 generation and verification.
797
798 Session and Session Management
799 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
800
801 Sessions are used in asymmetric cryptographic processing to store the immutable
802 data defined in asymmetric cryptographic transform which is further used in the
803 operation processing. Sessions typically stores information, such as, public
804 and private key information or domain params or prime modulus data i.e. immutable
805 across data sets. Crypto sessions cache this immutable data in a optimal way for the
806 underlying PMD and this allows further acceleration of the offload of Crypto workloads.
807
808 Like symmetric, the Crypto device framework provides APIs to allocate and initialize
809 asymmetric sessions for crypto devices, where sessions are mempool objects.
810 It is the application's responsibility to create and manage the session mempools.
811 Application using both symmetric and asymmetric sessions should allocate and maintain
812 different sessions pools for each type.
813
814 An application can use ``rte_cryptodev_get_asym_session_private_size()`` to
815 get the private size of asymmetric session on a given crypto device. This
816 function would allow an application to calculate the max device asymmetric
817 session size of all crypto devices to create a single session mempool.
818 If instead an application creates multiple asymmetric session mempools,
819 the Crypto device framework also provides ``rte_cryptodev_asym_get_header_session_size()`` to get
820 the size of an uninitialized session.
821
822 Once the session mempools have been created, ``rte_cryptodev_asym_session_create()``
823 is used to allocate an uninitialized asymmetric session from the given mempool.
824 The session then must be initialized using ``rte_cryptodev_asym_session_init()``
825 for each of the required crypto devices. An asymmetric transform chain
826 is used to specify the operation and its parameters. See the section below for
827 details on transforms.
828
829 When a session is no longer used, user must call ``rte_cryptodev_asym_session_clear()``
830 for each of the crypto devices that are using the session, to free all driver
831 private asymmetric session data. Once this is done, session should be freed using
832 ``rte_cryptodev_asym_session_free()`` which returns them to their mempool.
833
834 Asymmetric Sessionless Support
835 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
836 Currently asymmetric crypto framework does not support sessionless.
837
838 Transforms and Transform Chaining
839 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
840
841 Asymmetric Crypto transforms (``rte_crypto_asym_xform``) are the mechanism used
842 to specify the details of the asymmetric Crypto operation. Next pointer within
843 xform allows transform to be chained together. Also it is important to note that
844 the order in which the transforms are passed indicates the order of the chaining.
845
846 Not all asymmetric crypto xforms are supported for chaining. Currently supported
847 asymmetric crypto chaining is Diffie-Hellman private key generation followed by
848 public generation. Also, currently API does not support chaining of symmetric and
849 asymmetric crypto xfroms.
850
851 Each xform defines specific asymmetric crypto algo. Currently supported are:
852 * RSA
853 * Modular operations (Exponentiation and Inverse)
854 * Diffie-Hellman
855 * DSA
856 * None - special case where PMD may support a passthrough mode. More for diagnostic purpose
857
858 See *DPDK API Reference* for details on each rte_crypto_xxx_xform struct
859
860 Asymmetric Operations
861 ~~~~~~~~~~~~~~~~~~~~~
862
863 The asymmetric Crypto operation structure contains all the mutable data relating
864 to asymmetric cryptographic processing on an input data buffer. It uses either
865 RSA, Modular, Diffie-Hellman or DSA operations depending upon session it is attached
866 to.
867
868 Every operation must carry a valid session handle which further carries information
869 on xform or xform-chain to be performed on op. Every xform type defines its own set
870 of operational params in their respective rte_crypto_xxx_op_param struct. Depending
871 on xform information within session, PMD picks up and process respective op_param
872 struct.
873 Unlike symmetric, asymmetric operations do not use mbufs for input/output.
874 They operate on data buffer of type ``rte_crypto_param``.
875
876 See *DPDK API Reference* for details on each rte_crypto_xxx_op_param struct
877
878 Asymmetric crypto Sample code
879 -----------------------------
880
881 There's a unit test application test_cryptodev_asym.c inside unit test framework that
882 show how to setup and process asymmetric operations using cryptodev library.
883
884 The following sample code shows the basic steps to compute modular exponentiation
885 using 1024-bit modulus length using openssl PMD available in DPDK (performing other
886 crypto operations is similar except change to respective op and xform setup).
887
888 .. code-block:: c
889
890     /*
891      * Simple example to compute modular exponentiation with 1024-bit key
892      *
893      */
894     #define MAX_ASYM_SESSIONS   10
895     #define NUM_ASYM_BUFS       10
896
897     struct rte_mempool *crypto_op_pool, *asym_session_pool;
898     unsigned int asym_session_size;
899     int ret;
900
901     /* Initialize EAL. */
902     ret = rte_eal_init(argc, argv);
903     if (ret < 0)
904         rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n");
905
906     uint8_t socket_id = rte_socket_id();
907
908     /* Create crypto operation pool. */
909     crypto_op_pool = rte_crypto_op_pool_create(
910                                     "crypto_op_pool",
911                                     RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
912                                     NUM_ASYM_BUFS, 0, 0,
913                                     socket_id);
914     if (crypto_op_pool == NULL)
915         rte_exit(EXIT_FAILURE, "Cannot create crypto op pool\n");
916
917     /* Create the virtual crypto device. */
918     char args[128];
919     const char *crypto_name = "crypto_openssl";
920     snprintf(args, sizeof(args), "socket_id=%d", socket_id);
921     ret = rte_vdev_init(crypto_name, args);
922     if (ret != 0)
923         rte_exit(EXIT_FAILURE, "Cannot create virtual device");
924
925     uint8_t cdev_id = rte_cryptodev_get_dev_id(crypto_name);
926
927     /* Get private asym session data size. */
928     asym_session_size = rte_cryptodev_get_asym_private_session_size(cdev_id);
929
930     /*
931      * Create session mempool, with two objects per session,
932      * one for the session header and another one for the
933      * private asym session data for the crypto device.
934      */
935     asym_session_pool = rte_mempool_create("asym_session_pool",
936                                     MAX_ASYM_SESSIONS * 2,
937                                     asym_session_size,
938                                     0,
939                                     0, NULL, NULL, NULL,
940                                     NULL, socket_id,
941                                     0);
942
943     /* Configure the crypto device. */
944     struct rte_cryptodev_config conf = {
945         .nb_queue_pairs = 1,
946         .socket_id = socket_id
947     };
948     struct rte_cryptodev_qp_conf qp_conf = {
949         .nb_descriptors = 2048
950     };
951
952     if (rte_cryptodev_configure(cdev_id, &conf) < 0)
953         rte_exit(EXIT_FAILURE, "Failed to configure cryptodev %u", cdev_id);
954
955     if (rte_cryptodev_queue_pair_setup(cdev_id, 0, &qp_conf,
956                             socket_id, asym_session_pool) < 0)
957         rte_exit(EXIT_FAILURE, "Failed to setup queue pair\n");
958
959     if (rte_cryptodev_start(cdev_id) < 0)
960         rte_exit(EXIT_FAILURE, "Failed to start device\n");
961
962     /* Setup crypto xform to do modular exponentiation with 1024 bit
963          * length modulus
964          */
965     struct rte_crypto_asym_xform modex_xform = {
966                 .next = NULL,
967                 .xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX,
968                 .modex = {
969                         .modulus = {
970                                 .data =
971                                 (uint8_t *)
972                                 ("\xb3\xa1\xaf\xb7\x13\x08\x00\x0a\x35\xdc\x2b\x20\x8d"
973                                 "\xa1\xb5\xce\x47\x8a\xc3\x80\xf4\x7d\x4a\xa2\x62\xfd\x61\x7f"
974                                 "\xb5\xa8\xde\x0a\x17\x97\xa0\xbf\xdf\x56\x5a\x3d\x51\x56\x4f"
975                                 "\x70\x70\x3f\x63\x6a\x44\x5b\xad\x84\x0d\x3f\x27\x6e\x3b\x34"
976                                 "\x91\x60\x14\xb9\xaa\x72\xfd\xa3\x64\xd2\x03\xa7\x53\x87\x9e"
977                                 "\x88\x0b\xc1\x14\x93\x1a\x62\xff\xb1\x5d\x74\xcd\x59\x63\x18"
978                                 "\x11\x3d\x4f\xba\x75\xd4\x33\x4e\x23\x6b\x7b\x57\x44\xe1\xd3"
979                                 "\x03\x13\xa6\xf0\x8b\x60\xb0\x9e\xee\x75\x08\x9d\x71\x63\x13"
980                                 "\xcb\xa6\x81\x92\x14\x03\x22\x2d\xde\x55"),
981                                 .length = 128
982                         },
983                         .exponent = {
984                                 .data = (uint8_t *)("\x01\x00\x01"),
985                                 .length = 3
986                         }
987                 }
988     };
989     /* Create asym crypto session and initialize it for the crypto device. */
990     struct rte_cryptodev_asym_session *asym_session;
991     asym_session = rte_cryptodev_asym_session_create(asym_session_pool);
992     if (asym_session == NULL)
993         rte_exit(EXIT_FAILURE, "Session could not be created\n");
994
995     if (rte_cryptodev_asym_session_init(cdev_id, asym_session,
996                     &modex_xform, asym_session_pool) < 0)
997         rte_exit(EXIT_FAILURE, "Session could not be initialized "
998                     "for the crypto device\n");
999
1000     /* Get a burst of crypto operations. */
1001     struct rte_crypto_op *crypto_ops[1];
1002     if (rte_crypto_op_bulk_alloc(crypto_op_pool,
1003                             RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
1004                             crypto_ops, 1) == 0)
1005         rte_exit(EXIT_FAILURE, "Not enough crypto operations available\n");
1006
1007     /* Set up the crypto operations. */
1008     struct rte_crypto_asym_op *asym_op = crypto_ops[0]->asym;
1009
1010         /* calculate mod exp of value 0xf8 */
1011     static unsigned char base[] = {0xF8};
1012     asym_op->modex.base.data = base;
1013     asym_op->modex.base.length = sizeof(base);
1014         asym_op->modex.base.iova = base;
1015
1016     /* Attach the asym crypto session to the operation */
1017     rte_crypto_op_attach_asym_session(op, asym_session);
1018
1019     /* Enqueue the crypto operations in the crypto device. */
1020     uint16_t num_enqueued_ops = rte_cryptodev_enqueue_burst(cdev_id, 0,
1021                                             crypto_ops, 1);
1022
1023     /*
1024      * Dequeue the crypto operations until all the operations
1025      * are processed in the crypto device.
1026      */
1027     uint16_t num_dequeued_ops, total_num_dequeued_ops = 0;
1028     do {
1029         struct rte_crypto_op *dequeued_ops[1];
1030         num_dequeued_ops = rte_cryptodev_dequeue_burst(cdev_id, 0,
1031                                         dequeued_ops, 1);
1032         total_num_dequeued_ops += num_dequeued_ops;
1033
1034         /* Check if operation was processed successfully */
1035         if (dequeued_ops[0]->status != RTE_CRYPTO_OP_STATUS_SUCCESS)
1036                 rte_exit(EXIT_FAILURE,
1037                         "Some operations were not processed correctly");
1038
1039     } while (total_num_dequeued_ops < num_enqueued_ops);
1040
1041
1042 Asymmetric Crypto Device API
1043 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1044
1045 The cryptodev Library API is described in the
1046 `DPDK API Reference <http://dpdk.org/doc/api/>`_