doc: add asymmetric crypto in programmer guide
Update cryptodev programmer guide with description of asymmetric crypto framework in lib cryptodev. Signed-off-by: Shally Verma <shally.verma@caviumnetworks.com> Signed-off-by: Sunila Sahu <sunila.sahu@caviumnetworks.com> Signed-off-by: Ashish Gupta <ashish.gupta@caviumnetworks.com> Signed-off-by: Umesh Kartha <umesh.kartha@caviumnetworks.com> Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
This commit is contained in:
parent
b88c24bf25
commit
b9209dc219
@ -8,7 +8,7 @@ The cryptodev library provides a Crypto device framework for management and
|
||||
provisioning of hardware and software Crypto poll mode drivers, defining generic
|
||||
APIs which support a number of different Crypto operations. The framework
|
||||
currently only supports cipher, authentication, chained cipher/authentication
|
||||
and AEAD symmetric Crypto operations.
|
||||
and AEAD symmetric and asymmetric Crypto operations.
|
||||
|
||||
|
||||
Design Principles
|
||||
@ -158,8 +158,8 @@ Device Features and Capabilities
|
||||
Crypto devices define their functionality through two mechanisms, global device
|
||||
features and algorithm capabilities. Global devices features identify device
|
||||
wide level features which are applicable to the whole device such as
|
||||
the device having hardware acceleration or supporting symmetric Crypto
|
||||
operations,
|
||||
the device having hardware acceleration or supporting symmetric and/or asymmetric
|
||||
Crypto operations.
|
||||
|
||||
The capabilities mechanism defines the individual algorithms/functions which
|
||||
the device supports, such as a specific symmetric Crypto cipher,
|
||||
@ -445,7 +445,7 @@ Crypto workloads.
|
||||
|
||||
.. figure:: img/cryptodev_sym_sess.*
|
||||
|
||||
The Crypto device framework provides APIs to allocate and initizalize sessions
|
||||
The Crypto device framework provides APIs to allocate and initialize sessions
|
||||
for crypto devices, where sessions are mempool objects.
|
||||
It is the application's responsibility to create and manage the session mempools.
|
||||
This approach allows for different scenarios such as having a single session
|
||||
@ -787,14 +787,260 @@ using one of the crypto PMDs available in DPDK.
|
||||
num_dequeued_ops);
|
||||
} while (total_num_dequeued_ops < num_enqueued_ops);
|
||||
|
||||
|
||||
Asymmetric Cryptography
|
||||
-----------------------
|
||||
|
||||
Asymmetric functionality is currently not supported by the cryptodev API.
|
||||
The cryptodev library currently provides support for the following asymmetric
|
||||
Crypto operations; RSA, Modular exponentiation and inversion, Diffie-Hellman
|
||||
public and/or private key generation and shared secret compute, DSA Signature
|
||||
generation and verification.
|
||||
|
||||
Session and Session Management
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sessions are used in asymmetric cryptographic processing to store the immutable
|
||||
data defined in asymmetric cryptographic transform which is further used in the
|
||||
operation processing. Sessions typically stores information, such as, public
|
||||
and private key information or domain params or prime modulus data i.e. immutable
|
||||
across data sets. Crypto sessions cache this immutable data in a optimal way for the
|
||||
underlying PMD and this allows further acceleration of the offload of Crypto workloads.
|
||||
|
||||
Like symmetric, the Crypto device framework provides APIs to allocate and initialize
|
||||
asymmetric sessions for crypto devices, where sessions are mempool objects.
|
||||
It is the application's responsibility to create and manage the session mempools.
|
||||
Application using both symmetric and asymmetric sessions should allocate and maintain
|
||||
different sessions pools for each type.
|
||||
|
||||
An application can use ``rte_cryptodev_get_asym_session_private_size()`` to
|
||||
get the private size of asymmetric session on a given crypto device. This
|
||||
function would allow an application to calculate the max device asymmetric
|
||||
session size of all crypto devices to create a single session mempool.
|
||||
If instead an application creates multiple asymmetric session mempools,
|
||||
the Crypto device framework also provides ``rte_cryptodev_asym_get_header_session_size()`` to get
|
||||
the size of an uninitialized session.
|
||||
|
||||
Once the session mempools have been created, ``rte_cryptodev_asym_session_create()``
|
||||
is used to allocate an uninitialized asymmetric session from the given mempool.
|
||||
The session then must be initialized using ``rte_cryptodev_asym_session_init()``
|
||||
for each of the required crypto devices. An asymmetric transform chain
|
||||
is used to specify the operation and its parameters. See the section below for
|
||||
details on transforms.
|
||||
|
||||
When a session is no longer used, user must call ``rte_cryptodev_asym_session_clear()``
|
||||
for each of the crypto devices that are using the session, to free all driver
|
||||
private asymmetric session data. Once this is done, session should be freed using
|
||||
``rte_cryptodev_asym_session_free()`` which returns them to their mempool.
|
||||
|
||||
Asymmetric Sessionless Support
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Currently asymmetric crypto framework does not support sessionless.
|
||||
|
||||
Transforms and Transform Chaining
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Asymmetric Crypto transforms (``rte_crypto_asym_xform``) are the mechanism used
|
||||
to specify the details of the asymmetric Crypto operation. Next pointer within
|
||||
xform allows transform to be chained together. Also it is important to note that
|
||||
the order in which the transforms are passed indicates the order of the chaining.
|
||||
|
||||
Not all asymmetric crypto xforms are supported for chaining. Currently supported
|
||||
asymmetric crypto chaining is Diffie-Hellman private key generation followed by
|
||||
public generation. Also, currently API does not support chaining of symmetric and
|
||||
asymmetric crypto xfroms.
|
||||
|
||||
Each xform defines specific asymmetric crypto algo. Currently supported are:
|
||||
* RSA
|
||||
* Modular operations (Exponentiation and Inverse)
|
||||
* Diffie-Hellman
|
||||
* DSA
|
||||
* None - special case where PMD may support a passthrough mode. More for diagnostic purpose
|
||||
|
||||
See *DPDK API Reference* for details on each rte_crypto_xxx_xform struct
|
||||
|
||||
Asymmetric Operations
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The asymmetric Crypto operation structure contains all the mutable data relating
|
||||
to asymmetric cryptographic processing on an input data buffer. It uses either
|
||||
RSA, Modular, Diffie-Hellman or DSA operations depending upon session it is attached
|
||||
to.
|
||||
|
||||
Every operation must carry a valid session handle which further carries information
|
||||
on xform or xform-chain to be performed on op. Every xform type defines its own set
|
||||
of operational params in their respective rte_crypto_xxx_op_param struct. Depending
|
||||
on xform information within session, PMD picks up and process respective op_param
|
||||
struct.
|
||||
Unlike symmetric, asymmetric operations do not use mbufs for input/output.
|
||||
They operate on data buffer of type ``rte_crypto_param``.
|
||||
|
||||
See *DPDK API Reference* for details on each rte_crypto_xxx_op_param struct
|
||||
|
||||
Asymmetric crypto Sample code
|
||||
-----------------------------
|
||||
|
||||
There's a unit test application test_cryptodev_asym.c inside unit test framework that
|
||||
show how to setup and process asymmetric operations using cryptodev library.
|
||||
|
||||
The following sample code shows the basic steps to compute modular exponentiation
|
||||
using 1024-bit modulus length using openssl PMD available in DPDK (performing other
|
||||
crypto operations is similar except change to respective op and xform setup).
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/*
|
||||
* Simple example to compute modular exponentiation with 1024-bit key
|
||||
*
|
||||
*/
|
||||
#define MAX_ASYM_SESSIONS 10
|
||||
#define NUM_ASYM_BUFS 10
|
||||
|
||||
struct rte_mempool *crypto_op_pool, *asym_session_pool;
|
||||
unsigned int asym_session_size;
|
||||
int ret;
|
||||
|
||||
/* Initialize EAL. */
|
||||
ret = rte_eal_init(argc, argv);
|
||||
if (ret < 0)
|
||||
rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n");
|
||||
|
||||
uint8_t socket_id = rte_socket_id();
|
||||
|
||||
/* Create crypto operation pool. */
|
||||
crypto_op_pool = rte_crypto_op_pool_create(
|
||||
"crypto_op_pool",
|
||||
RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
|
||||
NUM_ASYM_BUFS, 0, 0,
|
||||
socket_id);
|
||||
if (crypto_op_pool == NULL)
|
||||
rte_exit(EXIT_FAILURE, "Cannot create crypto op pool\n");
|
||||
|
||||
/* Create the virtual crypto device. */
|
||||
char args[128];
|
||||
const char *crypto_name = "crypto_openssl";
|
||||
snprintf(args, sizeof(args), "socket_id=%d", socket_id);
|
||||
ret = rte_vdev_init(crypto_name, args);
|
||||
if (ret != 0)
|
||||
rte_exit(EXIT_FAILURE, "Cannot create virtual device");
|
||||
|
||||
uint8_t cdev_id = rte_cryptodev_get_dev_id(crypto_name);
|
||||
|
||||
/* Get private asym session data size. */
|
||||
asym_session_size = rte_cryptodev_get_asym_private_session_size(cdev_id);
|
||||
|
||||
/*
|
||||
* Create session mempool, with two objects per session,
|
||||
* one for the session header and another one for the
|
||||
* private asym session data for the crypto device.
|
||||
*/
|
||||
asym_session_pool = rte_mempool_create("asym_session_pool",
|
||||
MAX_ASYM_SESSIONS * 2,
|
||||
asym_session_size,
|
||||
0,
|
||||
0, NULL, NULL, NULL,
|
||||
NULL, socket_id,
|
||||
0);
|
||||
|
||||
/* Configure the crypto device. */
|
||||
struct rte_cryptodev_config conf = {
|
||||
.nb_queue_pairs = 1,
|
||||
.socket_id = socket_id
|
||||
};
|
||||
struct rte_cryptodev_qp_conf qp_conf = {
|
||||
.nb_descriptors = 2048
|
||||
};
|
||||
|
||||
if (rte_cryptodev_configure(cdev_id, &conf) < 0)
|
||||
rte_exit(EXIT_FAILURE, "Failed to configure cryptodev %u", cdev_id);
|
||||
|
||||
if (rte_cryptodev_queue_pair_setup(cdev_id, 0, &qp_conf,
|
||||
socket_id, asym_session_pool) < 0)
|
||||
rte_exit(EXIT_FAILURE, "Failed to setup queue pair\n");
|
||||
|
||||
if (rte_cryptodev_start(cdev_id) < 0)
|
||||
rte_exit(EXIT_FAILURE, "Failed to start device\n");
|
||||
|
||||
/* Setup crypto xform to do modular exponentiation with 1024 bit
|
||||
* length modulus
|
||||
*/
|
||||
struct rte_crypto_asym_xform modex_xform = {
|
||||
.next = NULL,
|
||||
.xform_type = RTE_CRYPTO_ASYM_XFORM_MODEX,
|
||||
.modex = {
|
||||
.modulus = {
|
||||
.data =
|
||||
(uint8_t *)
|
||||
("\xb3\xa1\xaf\xb7\x13\x08\x00\x0a\x35\xdc\x2b\x20\x8d"
|
||||
"\xa1\xb5\xce\x47\x8a\xc3\x80\xf4\x7d\x4a\xa2\x62\xfd\x61\x7f"
|
||||
"\xb5\xa8\xde\x0a\x17\x97\xa0\xbf\xdf\x56\x5a\x3d\x51\x56\x4f"
|
||||
"\x70\x70\x3f\x63\x6a\x44\x5b\xad\x84\x0d\x3f\x27\x6e\x3b\x34"
|
||||
"\x91\x60\x14\xb9\xaa\x72\xfd\xa3\x64\xd2\x03\xa7\x53\x87\x9e"
|
||||
"\x88\x0b\xc1\x14\x93\x1a\x62\xff\xb1\x5d\x74\xcd\x59\x63\x18"
|
||||
"\x11\x3d\x4f\xba\x75\xd4\x33\x4e\x23\x6b\x7b\x57\x44\xe1\xd3"
|
||||
"\x03\x13\xa6\xf0\x8b\x60\xb0\x9e\xee\x75\x08\x9d\x71\x63\x13"
|
||||
"\xcb\xa6\x81\x92\x14\x03\x22\x2d\xde\x55"),
|
||||
.length = 128
|
||||
},
|
||||
.exponent = {
|
||||
.data = (uint8_t *)("\x01\x00\x01"),
|
||||
.length = 3
|
||||
}
|
||||
}
|
||||
};
|
||||
/* Create asym crypto session and initialize it for the crypto device. */
|
||||
struct rte_cryptodev_asym_session *asym_session;
|
||||
asym_session = rte_cryptodev_asym_session_create(asym_session_pool);
|
||||
if (asym_session == NULL)
|
||||
rte_exit(EXIT_FAILURE, "Session could not be created\n");
|
||||
|
||||
if (rte_cryptodev_asym_session_init(cdev_id, asym_session,
|
||||
&modex_xform, asym_session_pool) < 0)
|
||||
rte_exit(EXIT_FAILURE, "Session could not be initialized "
|
||||
"for the crypto device\n");
|
||||
|
||||
/* Get a burst of crypto operations. */
|
||||
struct rte_crypto_op *crypto_ops[1];
|
||||
if (rte_crypto_op_bulk_alloc(crypto_op_pool,
|
||||
RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
|
||||
crypto_ops, 1) == 0)
|
||||
rte_exit(EXIT_FAILURE, "Not enough crypto operations available\n");
|
||||
|
||||
/* Set up the crypto operations. */
|
||||
struct rte_crypto_asym_op *asym_op = crypto_ops[0]->asym;
|
||||
|
||||
/* calculate mod exp of value 0xf8 */
|
||||
static unsigned char base[] = {0xF8};
|
||||
asym_op->modex.base.data = base;
|
||||
asym_op->modex.base.length = sizeof(base);
|
||||
asym_op->modex.base.iova = base;
|
||||
|
||||
/* Attach the asym crypto session to the operation */
|
||||
rte_crypto_op_attach_asym_session(op, asym_session);
|
||||
|
||||
/* Enqueue the crypto operations in the crypto device. */
|
||||
uint16_t num_enqueued_ops = rte_cryptodev_enqueue_burst(cdev_id, 0,
|
||||
crypto_ops, 1);
|
||||
|
||||
/*
|
||||
* Dequeue the crypto operations until all the operations
|
||||
* are processed in the crypto device.
|
||||
*/
|
||||
uint16_t num_dequeued_ops, total_num_dequeued_ops = 0;
|
||||
do {
|
||||
struct rte_crypto_op *dequeued_ops[1];
|
||||
num_dequeued_ops = rte_cryptodev_dequeue_burst(cdev_id, 0,
|
||||
dequeued_ops, 1);
|
||||
total_num_dequeued_ops += num_dequeued_ops;
|
||||
|
||||
/* Check if operation was processed successfully */
|
||||
if (dequeued_ops[0]->status != RTE_CRYPTO_OP_STATUS_SUCCESS)
|
||||
rte_exit(EXIT_FAILURE,
|
||||
"Some operations were not processed correctly");
|
||||
|
||||
} while (total_num_dequeued_ops < num_enqueued_ops);
|
||||
|
||||
|
||||
Crypto Device API
|
||||
~~~~~~~~~~~~~~~~~
|
||||
Asymmetric Crypto Device API
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The cryptodev Library API is described in the *DPDK API Reference* document.
|
||||
The cryptodev Library API is described in the
|
||||
`DPDK API Reference <http://dpdk.org/doc/api/>`_
|
||||
|
Loading…
x
Reference in New Issue
Block a user