1.. SPDX-License-Identifier: BSD-3-Clause 2 Copyright(c) 2016-2017 Intel Corporation. 3 4Cryptography Device Library 5=========================== 6 7The cryptodev library provides a Crypto device framework for management and 8provisioning of hardware and software Crypto poll mode drivers, defining generic 9APIs which support a number of different Crypto operations. The framework 10currently only supports cipher, authentication, chained cipher/authentication 11and AEAD symmetric Crypto operations. 12 13 14Design Principles 15----------------- 16 17The cryptodev library follows the same basic principles as those used in DPDKs 18Ethernet Device framework. The Crypto framework provides a generic Crypto device 19framework which supports both physical (hardware) and virtual (software) Crypto 20devices as well as a generic Crypto API which allows Crypto devices to be 21managed and configured and supports Crypto operations to be provisioned on 22Crypto poll mode driver. 23 24 25Device Management 26----------------- 27 28Device Creation 29~~~~~~~~~~~~~~~ 30 31Physical Crypto devices are discovered during the PCI probe/enumeration of the 32EAL function which is executed at DPDK initialization, based on 33their PCI device identifier, each unique PCI BDF (bus/bridge, device, 34function). Specific physical Crypto devices, like other physical devices in DPDK 35can be white-listed or black-listed using the EAL command line options. 36 37Virtual devices can be created by two mechanisms, either using the EAL command 38line options or from within the application using an EAL API directly. 39 40From the command line using the --vdev EAL option 41 42.. code-block:: console 43 44 --vdev 'crypto_aesni_mb0,max_nb_queue_pairs=2,socket_id=0' 45 46.. Note:: 47 48 * If DPDK application requires multiple software crypto PMD devices then required 49 number of ``--vdev`` with appropriate libraries are to be added. 50 51 * An Application with crypto PMD instaces sharing the same library requires unique ID. 52 53 Example: ``--vdev 'crypto_aesni_mb0' --vdev 'crypto_aesni_mb1'`` 54 55Our using the rte_vdev_init API within the application code. 56 57.. code-block:: c 58 59 rte_vdev_init("crypto_aesni_mb", 60 "max_nb_queue_pairs=2,socket_id=0") 61 62All virtual Crypto devices support the following initialization parameters: 63 64* ``max_nb_queue_pairs`` - maximum number of queue pairs supported by the device. 65* ``socket_id`` - socket on which to allocate the device resources on. 66 67 68Device Identification 69~~~~~~~~~~~~~~~~~~~~~ 70 71Each device, whether virtual or physical is uniquely designated by two 72identifiers: 73 74- A unique device index used to designate the Crypto device in all functions 75 exported by the cryptodev API. 76 77- A device name used to designate the Crypto device in console messages, for 78 administration or debugging purposes. For ease of use, the port name includes 79 the port index. 80 81 82Device Configuration 83~~~~~~~~~~~~~~~~~~~~ 84 85The configuration of each Crypto device includes the following operations: 86 87- Allocation of resources, including hardware resources if a physical device. 88- Resetting the device into a well-known default state. 89- Initialization of statistics counters. 90 91The rte_cryptodev_configure API is used to configure a Crypto device. 92 93.. code-block:: c 94 95 int rte_cryptodev_configure(uint8_t dev_id, 96 struct rte_cryptodev_config *config) 97 98The ``rte_cryptodev_config`` structure is used to pass the configuration 99parameters for socket selection and number of queue pairs. 100 101.. code-block:: c 102 103 struct rte_cryptodev_config { 104 int socket_id; 105 /**< Socket to allocate resources on */ 106 uint16_t nb_queue_pairs; 107 /**< Number of queue pairs to configure on device */ 108 }; 109 110 111Configuration of Queue Pairs 112~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 113 114Each Crypto devices queue pair is individually configured through the 115``rte_cryptodev_queue_pair_setup`` API. 116Each queue pairs resources may be allocated on a specified socket. 117 118.. code-block:: c 119 120 int rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id, 121 const struct rte_cryptodev_qp_conf *qp_conf, 122 int socket_id) 123 124 struct rte_cryptodev_qp_conf { 125 uint32_t nb_descriptors; /**< Number of descriptors per queue pair */ 126 }; 127 128 129Logical Cores, Memory and Queues Pair Relationships 130~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 131 132The Crypto device Library as the Poll Mode Driver library support NUMA for when 133a processor’s logical cores and interfaces utilize its local memory. Therefore 134Crypto operations, and in the case of symmetric Crypto operations, the session 135and the mbuf being operated on, should be allocated from memory pools created 136in the local memory. The buffers should, if possible, remain on the local 137processor to obtain the best performance results and buffer descriptors should 138be populated with mbufs allocated from a mempool allocated from local memory. 139 140The run-to-completion model also performs better, especially in the case of 141virtual Crypto devices, if the Crypto operation and session and data buffer is 142in local memory instead of a remote processor's memory. This is also true for 143the pipe-line model provided all logical cores used are located on the same 144processor. 145 146Multiple logical cores should never share the same queue pair for enqueuing 147operations or dequeuing operations on the same Crypto device since this would 148require global locks and hinder performance. It is however possible to use a 149different logical core to dequeue an operation on a queue pair from the logical 150core which it was enqueued on. This means that a crypto burst enqueue/dequeue 151APIs are a logical place to transition from one logical core to another in a 152packet processing pipeline. 153 154 155Device Features and Capabilities 156--------------------------------- 157 158Crypto devices define their functionality through two mechanisms, global device 159features and algorithm capabilities. Global devices features identify device 160wide level features which are applicable to the whole device such as 161the device having hardware acceleration or supporting symmetric Crypto 162operations, 163 164The capabilities mechanism defines the individual algorithms/functions which 165the device supports, such as a specific symmetric Crypto cipher, 166authentication operation or Authenticated Encryption with Associated Data 167(AEAD) operation. 168 169 170Device Features 171~~~~~~~~~~~~~~~ 172 173Currently 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 185Device Operation Capabilities 186~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 187 188Crypto capabilities which identify particular algorithm which the Crypto PMD 189supports are defined by the operation type, the operation transform, the 190transform identifier and then the particulars of the transform. For the full 191scope 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 198Each Crypto poll mode driver defines its own private array of capabilities 199for the operations it supports. Below is an example of the capabilities for a 200PMD which supports the authentication algorithm SHA1_HMAC and the cipher 201algorithm 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 251Capabilities Discovery 252~~~~~~~~~~~~~~~~~~~~~~ 253 254Discovering the features and capabilities of a Crypto device poll mode driver 255is 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 262This allows the user to query a specific Crypto PMD and get all the device 263features and capabilities. The ``rte_cryptodev_info`` structure contains all the 264relevant 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 285Operation Processing 286-------------------- 287 288Scheduling of Crypto operations on DPDK's application data path is 289performed using a burst oriented asynchronous API set. A queue pair on a Crypto 290device accepts a burst of Crypto operations using enqueue burst API. On physical 291Crypto devices the enqueue burst API will place the operations to be processed 292on the devices hardware input queue, for virtual devices the processing of the 293Crypto operations is usually completed during the enqueue call to the Crypto 294device. The dequeue burst API will retrieve any processed operations available 295from the queue pair on the Crypto device, from physical devices this is usually 296directly 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 298enqueue call. 299 300 301Private data 302~~~~~~~~~~~~ 303For session-based operations, the set and get API provides a mechanism for an 304application to store and retrieve the private data information stored along with 305the crypto session. 306 307For example, suppose an application is submitting a crypto operation with a session 308associated and wants to indicate private data information which is required to be 309used after completion of the crypto operation. In this case, the application can use 310the set API to set the private data and retrieve it using get API. 311 312.. code-block:: c 313 314 int rte_cryptodev_sym_session_set_private_data( 315 struct rte_cryptodev_sym_session *sess, void *data, uint16_t size); 316 317 void * rte_cryptodev_sym_session_get_private_data( 318 struct rte_cryptodev_sym_session *sess); 319 320 321For session-less mode, the private data information can be placed along with the 322``struct rte_crypto_op``. The ``rte_crypto_op::private_data_offset`` indicates the 323start of private data information. The offset is counted from the start of the 324rte_crypto_op including other crypto information such as the IVs (since there can 325be an IV also for authentication). 326 327 328Enqueue / Dequeue Burst APIs 329~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 330 331The burst enqueue API uses a Crypto device identifier and a queue pair 332identifier to specify the Crypto device queue pair to schedule the processing on. 333The ``nb_ops`` parameter is the number of operations to process which are 334supplied in the ``ops`` array of ``rte_crypto_op`` structures. 335The enqueue function returns the number of operations it actually enqueued for 336processing, a return value equal to ``nb_ops`` means that all packets have been 337enqueued. 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 344The dequeue API uses the same format as the enqueue API of processed but 345the ``nb_ops`` and ``ops`` parameters are now used to specify the max processed 346operations the user wishes to retrieve and the location in which to store them. 347The API call returns the actual number of processed operations returned, this 348can 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 356Operation Representation 357~~~~~~~~~~~~~~~~~~~~~~~~ 358 359An Crypto operation is represented by an rte_crypto_op structure, which is a 360generic metadata container for all necessary information required for the 361Crypto operation to be processed on a particular Crypto device poll mode driver. 362 363.. figure:: img/crypto_op.* 364 365The operation structure includes the operation type, the operation status 366and the session type (session-based/less), a reference to the operation 367specific data, which can vary in size and content depending on the operation 368being provisioned. It also contains the source mempool for the operation, 369if it allocated from a mempool. 370 371If Crypto operations are allocated from a Crypto operation mempool, see next 372section, there is also the ability to allocate private memory with the 373operation for applications purposes. 374 375Application software is responsible for specifying all the operation specific 376fields in the ``rte_crypto_op`` structure which are then used by the Crypto PMD 377to process the requested operation. 378 379 380Operation Management and Allocation 381~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 382 383The cryptodev library provides an API set for managing Crypto operations which 384utilize the Mempool Library to allocate operation buffers. Therefore, it ensures 385that the crytpo operation is interleaved optimally across the channels and 386ranks for optimal processing. 387A ``rte_crypto_op`` contains a field indicating the pool that it originated from. 388When 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 397During pool creation ``rte_crypto_op_init()`` is called as a constructor to 398initialize each Crypto operation which subsequently calls 399``__rte_crypto_op_reset()`` to configure any operation type specific fields based 400on the type parameter. 401 402 403``rte_crypto_op_alloc()`` and ``rte_crypto_op_bulk_alloc()`` are used to allocate 404Crypto 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 406allocate to a user so the operation is always in a good known state before use 407by 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 419its allocating pool. 420 421.. code-block:: c 422 423 void rte_crypto_op_free(struct rte_crypto_op *op) 424 425 426Symmetric Cryptography Support 427------------------------------ 428 429The cryptodev library currently provides support for the following symmetric 430Crypto operations; cipher, authentication, including chaining of these 431operations, as well as also supporting AEAD operations. 432 433 434Session and Session Management 435~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 436 437Sessions are used in symmetric cryptographic processing to store the immutable 438data defined in a cryptographic transform which is used in the operation 439processing of a packet flow. Sessions are used to manage information such as 440expand cipher keys and HMAC IPADs and OPADs, which need to be calculated for a 441particular Crypto operation, but are immutable on a packet to packet basis for 442a flow. Crypto sessions cache this immutable data in a optimal way for the 443underlying PMD and this allows further acceleration of the offload of 444Crypto workloads. 445 446.. figure:: img/cryptodev_sym_sess.* 447 448The Crypto device framework provides APIs to allocate and initizalize sessions 449for crypto devices, where sessions are mempool objects. 450It is the application's responsibility to create and manage the session mempools. 451This approach allows for different scenarios such as having a single session 452mempool for all crypto devices (where the mempool object size is big 453enough to hold the private session of any crypto device), as well as having 454multiple session mempools of different sizes for better memory usage. 455 456An application can use ``rte_cryptodev_sym_get_private_session_size()`` to 457get the private session size of given crypto device. This function would allow 458an application to calculate the max device session size of all crypto devices 459to create a single session mempool. 460If instead an application creates multiple session mempools, the Crypto device 461framework also provides ``rte_cryptodev_sym_get_header_session_size`` to get 462the size of an uninitialized session. 463 464Once the session mempools have been created, ``rte_cryptodev_sym_session_create()`` 465is used to allocate an uninitialized session from the given mempool. 466The session then must be initialized using ``rte_cryptodev_sym_session_init()`` 467for each of the required crypto devices. A symmetric transform chain 468is used to specify the operation and its parameters. See the section below for 469details on transforms. 470 471When a session is no longer used, user must call ``rte_cryptodev_sym_session_clear()`` 472for each of the crypto devices that are using the session, to free all driver 473private 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 477Transforms and Transform Chaining 478~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 479 480Symmetric Crypto transforms (``rte_crypto_sym_xform``) are the mechanism used 481to specify the details of the Crypto operation. For chaining of symmetric 482operations such as cipher encrypt and authentication generate, the next pointer 483allows transform to be chained together. Crypto devices which support chaining 484must publish the chaining of symmetric Crypto operations feature flag. 485 486Currently there are three transforms types cipher, authentication and AEAD. 487Also it is important to note that the order in which the 488transforms 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 507The API does not place a limit on the number of transforms that can be chained 508together but this will be limited by the underlying Crypto device poll mode 509driver which is processing the operation. 510 511.. figure:: img/crypto_xform_chain.* 512 513 514Symmetric Operations 515~~~~~~~~~~~~~~~~~~~~ 516 517The symmetric Crypto operation structure contains all the mutable data relating 518to performing symmetric cryptographic processing on a referenced mbuf data 519buffer. It is used for either cipher, authentication, AEAD and chained 520operations. 521 522As a minimum the symmetric operation must have a source data buffer (``m_src``), 523a valid session (or transform chain if in session-less mode) and the minimum 524authentication/ cipher/ AEAD parameters required depending on the type of operation 525specified in the session or the transform 526chain. 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 584Sample code 585----------- 586 587There are various sample applications that show how to use the cryptodev library, 588such as the L2fwd with Crypto sample application (L2fwd-crypto) and 589the IPSec Security Gateway application (ipsec-secgw). 590 591While these applications demonstrate how an application can be created to perform 592generic crypto operation, the required complexity hides the basic steps of 593how to use the cryptodev APIs. 594 595The following sample code shows the basic steps to encrypt several buffers 596with AES-CBC (although performing other crypto operations is similar), 597using 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 791Asymmetric Cryptography 792----------------------- 793 794Asymmetric functionality is currently not supported by the cryptodev API. 795 796 797Crypto Device API 798~~~~~~~~~~~~~~~~~ 799 800The cryptodev Library API is described in the *DPDK API Reference* document. 801