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