[dpdk-dev] [RFC v1 1/1] lib/cryptodev: add support of asymmetric crypto

Verma, Shally Shally.Verma at cavium.com
Thu Feb 15 06:32:57 CET 2018


HI Fiona

Thanks for your feedback. Response below.

>-----Original Message-----
>From: Trahe, Fiona [mailto:fiona.trahe at intel.com]
>Sent: 09 February 2018 23:43
>To: dev at dpdk.org; Athreya, Narayana Prasad <NarayanaPrasad.Athreya at cavium.com>; Murthy, Nidadavolu
><Nidadavolu.Murthy at cavium.com>; Sahu, Sunila <Sunila.Sahu at cavium.com>; Gupta, Ashish <Ashish.Gupta at cavium.com>; Verma,
>Shally <Shally.Verma at cavium.com>; Doherty, Declan <declan.doherty at intel.com>; Keating, Brian A <brian.a.keating at intel.com>;
>Griffin, John <john.griffin at intel.com>
>Cc: Trahe, Fiona <fiona.trahe at intel.com>; De Lara Guarch, Pablo <pablo.de.lara.guarch at intel.com>
>Subject: RE: [dpdk-dev] [RFC v1 1/1] lib/cryptodev: add support of asymmetric crypto
>
>Hi Shally,
>Comments below.
>
>> -----Original Message-----
>> From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Shally Verma
>> Sent: Tuesday, January 23, 2018 9:54 AM
>> To: Doherty, Declan <declan.doherty at intel.com>
>> Cc: dev at dpdk.org; pathreya at caviumnetworks.com; nmurthy at caviumnetworks.com;
>> ssahu at caviumnetworks.com; agupta at caviumnetworks.com; Shally Verma
>> <sverma at caviumnetworks.com>
>> Subject: [dpdk-dev] [RFC v1 1/1] lib/cryptodev: add support of asymmetric crypto
>>
>> From: Shally Verma <sverma at caviumnetworks.com>
>>
>> Add support for asymmetric crypto operations in DPDK lib cryptodev
>>
>> Key feature include:
>> - Only session based asymmetric crypto operations
>> - new get and set APIs for symmetric and asymmetric session private
>>   data and other informations
>> - APIs to create, configure and attch queue pair to asymmetric sessions
>> - new capabilities in struct device_info to indicate
>>   -- number of dedicated queue pairs available for symmetric and
>>      asymmetric operations, if any
>>   -- number of asymmetric sessions possible per qp
>>
>[Fiona] Though it's probably premature to include on the API have you considered
>providing for pre-loaded keys in future, i.e. the ability to wrap keys or refer to keys
>already stored securely on the device, as an alternative to passing the keys on the API?
>
[Shally] Current intention of DPDK asym spec is to expose HW capabilities to application to offload these compute intensive ops. 
Though your use-case is very much a practical requirement , but to achieve this I believe we need a layer above this spec and need different interfaces. Such as, some public/secure key library which provide interfaces to generate / store/ perform op using an opaque key handles which internally can use DPDK to do part of it. For such case, I envision dpdk (or library above) will likely run on some secure processor. Thus, currently I kept such use-case out of current spec scope.

>
>> Proposed asymmetric cryptographic operations are:
>> - rsa
>> - dsa
>> - deffie-hellman key pair generation and shared key computation
>> - ecdeffie-hellman
>> - fundamental elliptic curve operations
>> - elliptic curve DSA
>> - modular exponentiation and inversion
>>
>> This patch primarily defines PMD operations and device capabilities
>> to perform asymmetric crypto ops on queue pairs and intend to
>> invite feedbacks on current proposal so as to ensure it encompass
>> all kind of crypto devices with different capabilities and queue
>> pair management.
>>
>> List of TBDs:
>> - Currently, patch only updated for RSA xform and associated params.
>>   Other algoritms to be added in subsequent versions.
>> - per-service stats update
>>
>> Signed-off-by: Shally Verma <sverma at caviumnetworks.com>
>> ---
>>
>> It is derivative of RFC v2 asymmetric crypto patch series initiated by
>> Umesh Kartha(mailto:umesh.kartha at caviumnetworks.com):
>>
>>  http://dpdk.org/dev/patchwork/patch/24245/
>>  http://dpdk.org/dev/patchwork/patch/24246/
>>  http://dpdk.org/dev/patchwork/patch/24247/
>>
>> And inclusive of all review comments given on RFC v2.
>>  ( See complete discussion thread here:
>> http://dev.dpdk.narkive.com/yqTFFLHw/dpdk-dev-rfc-specifications-for-asymmetric-crypto-
>> algorithms#post12)
>>
>> Some of the RFCv2 Review comments pending for closure:
>> > " [Fiona] The count fn isn't used at all for sym - probably no need to add for asym
>>      better instead to remove the sym fn."
>>
>>      It is still present in dpdk-next-crypto for sym, so what has been decision
>>      on it?
>[Fiona] No change. The rte_cryptodev_ops fn is still not called so useless and should be removed.
>rte_cryptodev_queue_pair_count() returns the num_qps configured in
>rte_cryptodev_configure(), but never calls the PMD dev_ops.queue_pair_count().
>So cryptodev_sym_queue_pair_count_t should be deprecated.
>And no point in adding one for asym.
>

[Shally] Ok

>>
>> >"[Fiona] if each qp can handle only a specific service, i.e. a subset off the capabilities
>>     Indicated by the device capability list, there's a need for a new API to query
>>     the capability of a qp."
>>
>>     Current proposal doesn’t distinguish between device capability and qp capability.
>>     It rather leave such differences handling internal to PMDs. Thus no capability
>>     or API added for qp in current version. It is subject to revisit based on review
>>     feedback on current proposal.
>[Fiona] This would not work for some devices, comments below.
>
>>
>> - Sessionless Support.
>>     Current proposal only support Session-based because:
>>      1. All one-time setup i.e.  algos and associated params, such as, public-private keys
>>         or modulus length can be done in control path using session-init API
>>      2. it’s an easier way to dedicate qp to do specific service (using queue_pair_attach())
>>         which cannot be case in sessionless
>>      3. Couldn’t find any significant advantage going sessionless way. Also existing most of PMDs are
>> session-based.
>>
>>     It could be added in subsequent versions, if requirement is identified, based on review comment
>>     on this RFC.
>[Fiona] Our preference would be for sessionless, as it would need fewer API calls (no session_create/session_clear)
>and e.g. DH and ECDH sessions are likely to be only used for a single op. However this is not a blocker for
>this API, we can POC it later and propose an extension to the API if it gives a performance improvement.
>

[Shally] You mean you recommend to have session-less support along with session-based? 

>>
>> Summary
>> -------
>>
>> This section provides an overview of key feature enabled in current specification.
>> It comprise of key design challenges as have been identified on RFCv2 and
>> summary description of new interfaces and definitions added to handle same.
>>
>> Description
>> -----------
>>
>> This API set assumes that the max_nb_queue_pairs on a
>> device can be allocated to any mix of sym or asym. Some devices
>> may have a fixed max per service. Thus, rte_cryptodev_info
>> is updated with max_sym_nb_queues and max_asym_nb_queues with rule:
>>
>> max_nb_queue_pair = max_nb_sym_qp + max_nb_asym_qp.
>>
>> If device has no restrictions on qp to be used per service, such PMDs can leave
>> max_nb_sym_qp = max_nb_asym_qp = 0. In such case, application can setup any of
>> the service upto limit defined by max_nb_queue_pair.
>[Fiona] This seems awkward if a genuine 0  e.g. An appl wants to set up a sym qp, and
>sees that max_nb_queue_pair=4. Can't trust this - needs to look deeper. Sees
>max_nb_sym_qp=0. Doesn't know if that means it can set up 4 sym qps or no qps
>until it also checks max_nb_asym_qp. If=4 then it can't set up any sym qp, if=0 it can set up 4.
>Would it be better if
>	max_nb_queue_pair = max(max_nb_sym_qp, max_nb_asym_qp).
>	max_nb_sym_qp = 0..max_nb_queue_pair
>	max_nb_asym_qp = 0..max_nb_queue_pair
>

[Shally] Ok. I can change definition to replace 0 by max num for no-limit case with slight modification  to the condition i.e.
max_nb_queue_pair >=  max(max_nb_sym_qp, max_nb_asym_qp) 

because device can have distribution of (max_nb_queue_pair, max_nb_sym_qp, max_nb_asym_qp) as (4,4,4) or (4,3,1)
where total number of qp setup by application cannot exceed max_nb_queue_pairs.

>> Here, max_nb_sym_qp and max_nb_asym_qp, if non-zero, just define limit on qp which are
>> available for each service and *are not* ids to be used during qp setup and enqueue i.e.
>> if device supports both symmetric and asymmetric with n qp, then any of them
>> can be configured for symmetric or asymmetric subject to limit defined by
>> max_nb_sym_qp and max_nb_asym_qp. For example,
>> if device has 6 queues and 5 for symmetric and 1 for asymmetric that imply
>> application can setup only 1 out of any 6 qp for asymmetric and rest for
>> symmetric.
>>
>> Additionally, application can dedicate qp to perform specific service via optional
>> queue_pair_attach_sym/asym_session() API.
>[Fiona] This is too late - some devices have qps which need to know at setup which
>service they'll be used for, as they reserve resources based on the service.
>e.g. a device reports in info that it can support qps(max 4, max_sym 2, max asym 2)
>An application just wants to use 1 sym qp and 1 asym, so configures device with
>qps(max 2, max_sym 1, max asym 1)
>Now appl calls qp_setup for qp index 0. Wants to start with running asymmetric
>service and will set up the symmetric later, maybe in a separate thread.
>Our devices need to know at setup time which service will be used on the qp.
>So haven't been given enough information to setup the qp.
>
>Even if the PMD could set up service-agnostic qps and just map later, you
>suggest the qp_attach_sym/asym_session() would be optional. How could the appl
>make the decision whether to call it or not in above case? It needs to know whether
>the created qp is agnostic or not, so a capability must be reported by the PMD.
>OR the API should not be optional, must be called for every session.
>But that's perf impacting and not helpful if a device could support service-agnostic qps.
>
>I don't have a solution for service-agnostic qps. For our devices that's not necessary.
>Is it likely that anyone wants to set up a qp to process both sym and asym ops?
>Is it sufficient to accommodate qps which can support either
>service, but one must be picked at setup after which the qp supports only that service?
>How about the following - :
> - device reports in info qps(max, max_sym, max asym) where
>	max = max(max_sym, max_asym).
>	max_sym = 0..max
>	max_asym = 0..max
>	So if a device reports 4,2,2, it has 4 total, 2 can be setup for sym, 2 for asym
>	Or if it reports 4,4,4, all 4 of them can be setup as sym or all 4 as
>	asym or a mix, but total setup can't be more than 4.
> - appl configures qps(max, max_sym, max_asym)
>	If it specifies 4,1,3 it wants to use 4 in total, 1 for sym, 3 for asym.
>	If it specifies 1,1,0 it wants to use 1 in total, 1 for sym, 0 for asym.
>	The numbers it configures must be <= those reported in info.
> - appl calls qp_setup(dev, qp, service) where service = sym or asym
>	qp index must be between 0..max-1
>	The PMD maps that index to an internal qp which can support the requested service.
>	If qp_setup is called on an index and the max configured qps have already
>	been setup for that service then the setup fails.
>In case the appl forgets which qp it set up for which service, I think it would be necessary to add a new API
>	rte_cryptodev_qp_info() which would return what service is configured on the qp
>
>If it's necessary to support service-agnostic qps, then one way would be to specify a third service above as
> - sym+asym.
>And have devices report max_sym_asym_qps?
>
>It's difficult to find a solution for this without breaking the current API - see simpler
>alternative below.
>
>> Except the ones mentioned above, specification doesn't define any restrictions on
>> enqueue/dequeue API for different crypto services. Application can enqueue both symmetric
>> and asymmetric operations to same device and qp if device info indicate support of both
>> symmetric and asymmetric and qp is not dedicated to any. However in practice, it could
>> result in head-of-line blocking due to the asym ops taking longer than the symmetric ops.
>>
>> Some HW accelerators avoid this issue by supporting sym and asym ops
>> on different qps on the same device.  Such devices can set max_nb_sym_qp and
>> max_nb_asym_qp to number of queues available for each respective service.
>>
>> This may give problem in indexing on enqueue/dequeue i.e.
>> if 2 asym qps and 2 sym qps are created on the same device,
>> the queue_pair_ids are duplicated. To handle such scenario,
>> 2 alternatives are proposed for PMD design:
>>
>> 1. Allow all qp to input any operation type virtually. Say,
>>
>>     Consider device with symmetric and asymmetric capability having
>>     max_nb_queue_pair as 6, then by design, all 6 are capable to input
>>     both op types.
>>
>>     If PMD uses fixed set of qp, then internally, can map qp id to
>>     actual physical qp id to be used according to session/op type.
>>     If such mapping is done on data path, may impact performance of PMDs.
>>     Thus, to handle such mapping out of data path, library provides an API
>>     queue_pair_attach_sym/asym_session() which facilitate application to
>>     dedicate qp id to perform specific (sym/asym) service in control path
>>     and should be called before 1st call to enqueue_burst().
>>     Here PMD can bind app provided logical qp id to actual physical qp id to use
>>     depending on session type , OR alternatively
>>
>> 2. PMDs can split it into two PMDs, one with symmetric ONLY capability and other
>>     with asymmetric ONLY capability (also proposed by Fiona in RFCv2).
>>     This may require some  changes to EAL to facilitate pci device sharing between
>>     PMDs, enabling separation of sym and  asym services onto different PMDs.
>>     As per RFCv2 feedback, Intel  proposed to submit a patch to  enable this.
>[Fiona] The eal changes were problematic, and feedback from the Dublin userspace
>event last September was that several others have tried similar but reverted to resolving
>the problem within the PMD. This is what we are also in the process of doing.
>With this we intend to avoid all the above complications.
>i.e. one pci device, in its probe fn, can create multiple API device instances.
>One instance of cryptodev will provide a sym crypto service, one instance of
>compressdev will provide a compression service and a second cryptodev instance will
>provide the asymmetric service. All qps on each API device instance can then support all
>of the capabilities reported by that device.
>
>A suggestion for keeping the simplicity on the API would be to follow the same pattern.
>i.e. don't provide any support for specification of sym or asym qps. Expect all
>qps on each device to support all capabilities reported.
>
>

[Shally] Initially I had thought of same proposal to add an input field in qp_conf so that PMD can know at qp_setup time which service it going to be used for.
However looking that spec already had qp_attach_sym/asym APIs and also the possibility that some device can support service - agnostic qp, I initiated with current proposal.
I marked them optional with a disclaimer that , if not attached, then PMD will then need to map logical qpid to physical during enqueue_burst() which might result in impacted performance. 
This is particularly applicable to devices which internally have fixed qps per each service and set max_nb_sym/asym_qp to indicate same.
And thus for such devices, I primarily recommended that they should appear as two separate PMDs where one support sym and other asym. 
However, only point to is to see how well suited is this for each device driver design as it might rather turn to be simpler for some implementation to just have single way to dedicate a qp to a service via attach or qp_setup change than having two separate instances.

But, I concur from your thoughts. We can start with simple definition and remove concept of max_nb_sym_qp and max_nb_asym_qp in first version and say 
-if device support service agnostic qp, that means all of its qp can be set up for any service. PMD can show in its feature flag support for symmetric and asymmetric crypto. Application can set up qp the way it want, spec define no recommended way of usage here 
-if device has fixed set of qp per each service, then it should split itself into two : symmetric only and asymmetric only. 

This is well suited for session-less also.  IMO, If any issues reported with these rules, then we can add this support later based on the then identified requirement. However, if we end up adding the support back of max_nb_sym/asym_qp in spec later, then attach/detach_qp APIs will not be sufficient as they are session specific. Given that, having an input param during qp_setup() is more generic way that suit both session and sessionless way. Does this all sounds right?
 
I will wait to close on this design discussion first before giving feedback to rest of the comment further below. But consider all feedback regarding typo and licensing as acknowledged.

Thanks
Shally

>> 3. Some of the other alternatives were also suggested on RFCv2 as summarised here:
>>     "[Fiona] One alternative is to use different qp_ids for sym and asym.
>>       Remove the queue_pair_id from the xxx_queue_pair_setup fns
>>       and instead return the id. So e.g. if sym_queue_pair_setup() is called, then
>>       asym_queue_pair_setup(), then sym_queue_pair_setup() qp_id 0 and 2 would be
>>       sym qps and qp_id 1 would be an asym qp. Instead of separate
>>       dev->data->asym_queue_pairs and dev->data->sym_queue_pairs arrays there
>>       would be one common array. Another alternative is to use separate APIs i.e.
>>       rte_cryptodev_sym_enqueue_burst rte_cryptodev_asym_enqueue_burst."
>>
>>      We believe eithr of above proposed 1st two solutions(against point 1 and 2) suffice to achieve purpose.
>>      Thus, we don’t realize need to change notion of qp_setup() or add new enqueue_burst() variant
>>      for asym at current stage. However it is subject to revisit, if any requirement is identified.
>>
>> ---
>>  lib/librte_cryptodev/Makefile                  |   1 +
>>  lib/librte_cryptodev/rte_crypto.h              |  39 +-
>>  lib/librte_cryptodev/rte_crypto_asym.h         | 949 +++++++++++++++++++++++++
>>  lib/librte_cryptodev/rte_cryptodev.c           | 287 ++++++++
>>  lib/librte_cryptodev/rte_cryptodev.h           | 358 +++++++++-
>>  lib/librte_cryptodev/rte_cryptodev_pmd.c       |  19 +-
>>  lib/librte_cryptodev/rte_cryptodev_pmd.h       | 154 +++-
>>  lib/librte_cryptodev/rte_cryptodev_version.map |  21 +
>>  8 files changed, 1811 insertions(+), 17 deletions(-)
>>
>> diff --git a/lib/librte_cryptodev/Makefile b/lib/librte_cryptodev/Makefile
>> index bba8dee..dec325b 100644
>> --- a/lib/librte_cryptodev/Makefile
>> +++ b/lib/librte_cryptodev/Makefile
>> @@ -21,6 +21,7 @@ SRCS-y += rte_cryptodev.c rte_cryptodev_pmd.c
>>  # export include files
>>  SYMLINK-y-include += rte_crypto.h
>>  SYMLINK-y-include += rte_crypto_sym.h
>> +SYMLINK-y-include += rte_crypto_asym.h
>>  SYMLINK-y-include += rte_cryptodev.h
>>  SYMLINK-y-include += rte_cryptodev_pmd.h
>>
>> diff --git a/lib/librte_cryptodev/rte_crypto.h b/lib/librte_cryptodev/rte_crypto.h
>> index 95cf861..e8c0bac 100644
>> --- a/lib/librte_cryptodev/rte_crypto.h
>> +++ b/lib/librte_cryptodev/rte_crypto.h
>> @@ -23,6 +23,7 @@
>>  #include <rte_common.h>
>>
>>  #include "rte_crypto_sym.h"
>> +#include "rte_crypto_asym.h"
>>
>>  /** Crypto operation types */
>>  enum rte_crypto_op_type {
>> @@ -30,6 +31,8 @@ enum rte_crypto_op_type {
>>  	/**< Undefined operation type */
>>  	RTE_CRYPTO_OP_TYPE_SYMMETRIC,
>>  	/**< Symmetric operation */
>> +	RTE_CRYPTO_OP_TYPE_ASYMMETRIC
>> +	/**< Asymmetric operation */
>>  };
>>
>>  /** Status of crypto operation */
>> @@ -97,6 +100,10 @@ struct rte_crypto_op {
>>  	union {
>>  		struct rte_crypto_sym_op sym[0];
>>  		/**< Symmetric operation parameters */
>> +
>> +		struct rte_crypto_asym_op asym[0];
>> +		/**< Asymmetric operation parameters */
>> +
>>  	}; /**< operation specific parameters */
>>  };
>>
>> @@ -117,6 +124,9 @@ struct rte_crypto_op {
>>  	case RTE_CRYPTO_OP_TYPE_SYMMETRIC:
>>  		__rte_crypto_sym_op_reset(op->sym);
>>  		break;
>> +	case RTE_CRYPTO_OP_TYPE_ASYMMETRIC:
>> +		__rte_crypto_asym_op_reset(op->asym);
>> +		break;
>>  	case RTE_CRYPTO_OP_TYPE_UNDEFINED:
>>  	default:
>>  		break;
>> @@ -124,7 +134,7 @@ struct rte_crypto_op {
>>  }
>>
>>  /**
>> - * Private data structure belonging to a crypto symmetric operation pool.
>> + * Private data structure belonging to a crypto operation pool.
>>   */
>>  struct rte_crypto_op_pool_private {
>>  	enum rte_crypto_op_type type;
>> @@ -283,9 +293,14 @@ struct rte_crypto_op_pool_private {
>>  	if (likely(op->mempool != NULL)) {
>>  		priv_size = __rte_crypto_op_get_priv_data_size(op->mempool);
>>
>> -		if (likely(priv_size >= size))
>> -			return (void *)((uint8_t *)(op + 1) +
>> +		if (likely(priv_size >= size)) {
>> +			if (op->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC)
>> +				return (void *)((uint8_t *)(op + 1) +
>>  					sizeof(struct rte_crypto_sym_op));
>> +			if (op->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC)
>> +				return (void *)((uint8_t *)(op+1) +
>> +					sizeof(struct rte_crypto_asym_op));
>> +		}
>>  	}
>>
>>  	return NULL;
>> @@ -388,6 +403,24 @@ struct rte_crypto_op_pool_private {
>>  	return __rte_crypto_sym_op_attach_sym_session(op->sym, sess);
>>  }
>>
>> +/**
>> + * Attach a asymmetric session to a crypto operation
>> + *
>> + * @param	op	crypto operation, must be of type asymmetric
>> + * @param	sess	cryptodev session
>> + */
>> +static inline int
>> +rte_crypto_op_attach_asym_session(struct rte_crypto_op *op,
>> +		struct rte_cryptodev_asym_session *sess)
>> +{
>> +	if (unlikely(op->type != RTE_CRYPTO_OP_TYPE_ASYMMETRIC))
>> +		return -1;
>> +
>> +	op->sess_type = RTE_CRYPTO_OP_WITH_SESSION;
>> +
>> +	return __rte_crypto_op_attach_asym_session(op->asym, sess);
>> +}
>> +
>>  #ifdef __cplusplus
>>  }
>>  #endif
>> diff --git a/lib/librte_cryptodev/rte_crypto_asym.h b/lib/librte_cryptodev/rte_crypto_asym.h
>> new file mode 100644
>> index 0000000..27caf55
>> --- /dev/null
>> +++ b/lib/librte_cryptodev/rte_crypto_asym.h
>> @@ -0,0 +1,949 @@
>> +/*
>> + *   BSD LICENSE
>> + *
>[Fiona] Use SPDX license
>
>> + *   Copyright (C) Cavium networks Ltd. 2017.
>> + *
>> + *   Redistribution and use in source and binary forms, with or without
>> + *   modification, are permitted provided that the following conditions
>> + *   are met:
>> + *
>> + *     * Redistributions of source code must retain the above copyright
>> + *       notice, this list of conditions and the following disclaimer.
>> + *     * Redistributions in binary form must reproduce the above copyright
>> + *       notice, this list of conditions and the following disclaimer in
>> + *       the documentation and/or other materials provided with the
>> + *       distribution.
>> + *     * Neither the name of Cavium Networks nor the names of its
>> + *       contributors may be used to endorse or promote products derived
>> + *       from this software without specific prior written permission.
>> + *
>> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>> + */
>> +
>> +#ifndef _RTE_CRYPTO_ASYM_H_
>> +#define _RTE_CRYPTO_ASYM_H_
>> +
>> +/**
>> + * @file rte_crypto_asym.h
>> + *
>> + * RTE Definitions for Asymmetric Cryptography
>> + *
>> + * Defines asymmetric algorithms and modes, as well as supported
>> + * asymmetric crypto operations.
>> + */
>> +
>> +#ifdef __cplusplus
>> +extern "C" {
>> +#endif
>> +
>> +#include <string.h>
>> +#include <stdint.h>
>> +#include <rte_mbuf.h>
>> +#include <rte_memory.h>
>> +#include <rte_mempool.h>
>> +#include <rte_common.h>
>> +
>> +typedef struct rte_crypto_xform_param_t {
>> +	uint8_t *data;
>> +	phys_addr_t phys_addr;
>[Fiona] Use iova
>
>> +	size_t length;
>> +} rte_crypto_xform_param;
>> +
>> +typedef struct rte_crypto_op_param_t {
>> +	uint8_t *data;
>> +	phys_addr_t phys_addr;
>> +	size_t length;
>> +} rte_crypto_op_param;
>> +
>[Fiona]  specify that above lengths are bytes - asym uses bit lengths in some contexts.
>Above structs are identical - why not use a single struct?
>rte_crypto_param_t
>
>mention
>> +/**
>> + * Asymmetric crypto transformation types.
>> + * Each xform type maps to one asymmetric algorithm
>> + * performing specific operation
>> + *
>> + */
>> +enum rte_crypto_asym_xform_type {
>> +	RTE_CRYPTO_ASYM_XFORM_NONE = 0,
>> +	/**< Xform type None. May be supported by
>> +	 * PMD to support passthrough op for debugging
>> +	 * purpose.
>> +	 * if xform_type none , op_type is disregarded.
>> +	 */
>> +	RTE_CRYPTO_ASYM_XFORM_RSA,
>> +	/**< RSA. Performs Encrypt, Decrypt, Sign and Verify
>> +	 * Refer to rte_crypto_asym_op_type
>> +	 */
>> +	RTE_CRYPTO_ASYM_XFORM_MODEX,
>> +	/**< Modular Exponentiation
>> +	 * Refer to rte_crypto_asym_op_type
>> +	 */
>> +	RTE_CRYPTO_ASYM_XFORM_DH,
>> +	/**< Deffie-Hellman. Perform Key Generate, Key Compute
>> +	 * Refer to rte_crypto_asym_op_type
>> +	 */
>> +	RTE_CRYPTO_ASYM_XFORM_ECDH,
>> +	/**< Elliptic Curve Deffie-Hellman.
>> +	 * Perform Key Genearate, Key Check and Key Compute
>[Fiona] typo: generate
>
>> +	 * Refer to rte_crypto_asym_op_type
>> +	 */
>> +	RTE_CRYPTO_ASYM_XFORM_DSA,
>> +	/**< Digital Signature Algorithm
>> +	 * Performs Signature verification and Generation
>> +	 * Refer to rte_crypto_asym_op_type
>> +	 */
>> +	RTE_CRYPTO_ASYM_XFORM_ECDSA,
>> +	/**< Elliptic Curve Digital Signature Algorithm.
>> +	 * Performs Signature Generation, and Verification.
>> +	 * Refer to rte_crypto_asym_op_type
>> +	 */
>[Fiona] typo in both above: Signature Generation and Verification
>
>> +	RTE_CRYPTO_ASYM_XFORM_FECC,
>> +	/**< Fundamental Elliptic curve operations.
>> +	 * Perform elliptic curve operation:
>> +	 * add, double point, multiplication
>> +	 * Refer to enum rte_crypto_fecc_optype
>> +	 */
>> +	RTE_CRYPTO_ASYM_XFORM_MODINV,
>> +	/**< Modular Inverse */
>[Fiona] would be nicer to group modinv with modexp
>
>> +	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
>> +	/**< End of list */
>> +};
>> +
>> +/**
>> + * Asymmetric cryptogr operation type variants
>[Fiona] typo: Use crypto or cryptographic
>
>> + */
>> +enum rte_crypto_asym_op_type {
>> +	RTE_CRYPTO_ASYM_OP_NOT_SPECIFIED = 1,
>[Fiona] Why does this start at 1?
>And is it necessary?
>
>> +	/**< Operation unspecified */
>> +	RTE_CRYPTO_ASYM_OP_ENCRYPT,
>> +	/**< Asymmetric encrypt operation */
>> +	RTE_CRYPTO_ASYM_OP_DECRYPT,
>> +	/**< Asymmetric Decrypt operation */
>> +	RTE_CRYPTO_ASYM_OP_SIGN,
>> +	/**< Signature generation operation */
>> +	RTE_CRYPTO_ASYM_OP_VERIFY,
>> +	/**< Signature verification operation */
>> +	RTE_CRYPTO_ASYM_OP_KEY_PAIR_GENERATION,
>> +	/**< Public/Private key pair generation operation */
>[Fiona] In the comment, clarify that this is for DH and ECDH, and for the
> generation of the public key (and optionally the private key?)
>
>> +	RTE_CRYPTO_ASYM_OP_SHARED_KEY_COMPUTATION,
>> +	/**< DH private key computation operation */
>[Fiona] In the comment, replace "private key" with "shared secret key".
>Also clarify that this is for both DH and ECDH
>
>> +	RTE_CRYPTO_ASYM_OP_ECDH_OP_KEY_CHECK,
>> +	/**< ECDH public key validity check operation */
>> +	RTE_CRYPTO_ASYM_OP_LIST_END
>> +};
>> +
>> +/**
>> + * Padding types for RSA signature.
>> + */
>> +enum rte_crypto_rsa_padding_type {
>> +	RTE_CRYPTO_RSA_PADDING_NOT_SPECIFIED = 1,
>> +	/**< RSA no padding scheme */
>> +	RTE_CRYPTO_RSA_PADDING_BT1,
>> +	/**< RSA PKCS#1 padding BT1 scheme */
>> +	RTE_CRYPTO_RSA_PADDING_BT2,
>> +	/**< RSA PKCS#1 padding BT2 scheme */
>[Fiona] In the name, I would add _PKCS1_V1.5_, to make this clearer. Also in the comment, clarify that BT is
>for "block type". Also clarify how these map to the block type in PKCS#1 v1.5
>(https://tools.ietf.org/html/rfc2313), which specifies three values for block type.
>
>> +	RTE_CRYPTO_RSA_PADDING_OAEP,
>> +	/**< RSA PKCS#1 OAEP padding scheme */
>> +	RTE_CRYPTO_RSA_PADDING_PSS,
>> +	/**< RSA PKCS#1 PSS padding scheme */
>> +	RTE_CRYPTO_RSA_PADDING_TYPE_LIST_END
>> +};
>> +
>> +
>> +/**
>> + * Fundamental ECC operation type variants.
>> + */
>> +enum rte_crypto_fecc_optype {
>> +	RTE_CRYPTO_FECC_OP_NOT_SPECIFIED = 1,
>> +	/**< FECC operation type unspecified */
>[Fiona] as above. Why 1? And is it needed?
>
>> +	RTE_CRYPTO_FECC_OP_POINT_ADD,
>> +	/**< Fundamental ECC point addition operation */
>> +	RTE_CRYPTO_FECC_OP_POINT_DBL,
>> +	/**< Fundamental ECC point doubling operation */
>> +	RTE_CRYPTO_FECC_OP_POINT_MULTIPLY,
>> +	/**< Fundamental ECC point multiplication operation */
>> +	RTE_CRYPTO_FECC_OP_LIST_END
>> +};
>> +
>> +#define RTE_CRYPTO_EC_CURVE_NOT_SPECIFIED  -1
>[Fiona] Wouldn't it be better to put this back in as the initial value in the enum as originally done?
>Else will there not be a compiler warning if a param of that enum type is
>initialised to above #define?
>And are _BINARY and _PRIME values needed in this case?
>
>> +/**
>> + * ECC list of curves.
>> + */
>> +enum rte_crypto_ec_prime_curve {
>> +	/**< Unspecified or empty curve id */
>[Fiona] Remove stray comment
>> +	RTE_CRYPTO_EC_CURVE_secp112r1,
>> +	/**< SECG/WTLS curve over a 112 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_secp112r2,
>> +	/**< SECG curve over a 112 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_secp128r1,
>> +	/**< SECG curve over a 128 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_secp128r2,
>> +	/**< SECG curve over a 128 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_secp160k1,
>> +	/**< SECG curve over a 160 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_secp160r1,
>> +	/**< SECG curve over a 160 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_secp160r2,
>> +	/**< SECG/WTLS curve over a 160 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_secp192k1,
>> +	/**< SECG curve over a 192 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_secp224k1,
>> +	/**< SECG curve over a 224 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_secp224r1,
>> +	/**< NIST/SECG curve over a 224 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_secp256k1,
>> +	/**< SECG curve over a 256 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_secp384r1,
>> +	/**< NIST/SECG curve over a 384 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_secp521r1,
>> +	/**< NIST/SECG curve over a 521 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_prime192v1,
>> +	/**< NIST/X9.62/SECG curve over a 192 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_prime192v2,
>> +	/**< X9.62 curve over a 192 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_prime192v3,
>> +	/**< X9.62 curve over a 192 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_prime239v1,
>> +	/**< X9.62 curve over a 239 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_prime239v2,
>> +	/**< X9.62 curve over a 239 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_prime239v3,
>> +	/**< X9.62 curve over a 239 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_prime256v1,
>> +	/**< X9.62/SECG curve over a 256 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_wap_wsg_idm_ecid_wtls6,
>> +	/**< SECG/WTLS curve over a 112 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_wap_wsg_idm_ecid_wtls7,
>> +	/**< SECG/WTLS curve over a 160 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_wap_wsg_idm_ecid_wtls8,
>> +	/**< WTLS curve over a 112 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_wap_wsg_idm_ecid_wtls9,
>> +	/**< WTLS curve over a 160 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_wap_wsg_idm_ecid_wtls12,
>> +	/**< WTLS curve over a 224 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_brainpoolP160r1,
>> +	/**< RFC 5639 curve over a 160 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_brainpoolP160t1,
>> +	/**< RFC 5639 curve over a 160 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_brainpoolP192r1,
>> +	/**< RFC 5639 curve over a 192 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_brainpoolP192t1,
>> +	/**< RFC 5639 curve over a 192 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_brainpoolP224r1,
>> +	/**< RFC 5639 curve over a 224 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_brainpoolP224t1,
>> +	/**< RFC 5639 curve over a 224 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_brainpoolP256r1,
>> +	/**< RFC 5639 curve over a 256 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_brainpoolP256t1,
>> +	/**< RFC 5639 curve over a 256 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_brainpoolP320r1,
>> +	/**< RFC 5639 curve over a 320 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_brainpoolP320t1,
>> +	/**< RFC 5639 curve over a 320 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_brainpoolP384r1,
>> +	/**< RFC 5639 curve over a 384 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_brainpoolP384t1,
>> +	/**< RFC 5639 curve over a 384 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_brainpoolP512r1,
>> +	/**< RFC 5639 curve over a 512 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_brainpoolP512t1,
>> +	/**< RFC 5639 curve over a 512 bit prime field */
>> +	RTE_CRYPTO_EC_CURVE_x25519,
>> +	/**< Curve 25519 */
>> +	RTE_CRYPTO_EC_PCURVE_LIST_END
>> +};
>> +
>> +enum rte_crypto_ec_binary_curve {
>> +	/**< Unspecified or empty curve id */
>[Fiona] remove stray comment
>> +	RTE_CRYPTO_EC_CURVE_sect113r1,
>> +	/**< SECG curve over a 113 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_sect113r2,
>> +	/**< SECG curve over a 113 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_sect131r1,
>> +	/**< SECG/WTLS curve over a 131 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_sect131r2,
>> +	/**< SECG curve over a 131 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_sect163k1,
>> +	/**< NIST/SECG/WTLS curve over a 163 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_sect163r1,
>> +	/**< SECG curve over a 163 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_sect163r2,
>> +	/**< NIST/SECG curve over a 163 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_sect193r1,
>> +	/**< SECG curve over a 193 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_sect193r2,
>> +	/**< SECG curve over a 193 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_sect233k1,
>> +	/**< NIST/SECG/WTLS curve over a 233 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_sect233r1,
>> +	/**< NIST/SECG/WTLS curve over a 233 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_sect239k1,
>> +	/**< SECG curve over a 239 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_sect283k1,
>> +	/**< NIST/SECG curve over a 283 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_sect283r1,
>> +	/**< NIST/SECG curve over a 283 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_sect409k1,
>> +	/**< NIST/SECG curve over a 409 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_sect409r1,
>> +	/**< NIST/SECG curve over a 409 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_sect571k1,
>> +	/**< NIST/SECG curve over a 571 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_sect571r1,
>> +	/**< NIST/SECG curve over a 571 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_c2pnb163v1,
>> +	/**< X9.62 curve over a 163 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_c2pnb163v2,
>> +	/**< X9.62 curve over a 163 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_c2pnb163v3,
>> +	/**< X9.62 curve over a 163 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_c2pnb176v1,
>> +	/**< X9.62 curve over a 176 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_c2tnb191v1,
>> +	/**< X9.62 curve over a 191 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_c2tnb191v2,
>> +	/**< X9.62 curve over a 191 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_c2tnb191v3,
>> +	/**< X9.62 curve over a 191 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_c2pnb208w1,
>> +	/**< X9.62 curve over a 208 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_c2tnb239v1,
>> +	/**< X9.62 curve over a 239 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_c2tnb239v2,
>> +	/**< X9.62 curve over a 239 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_c2tnb239v3,
>> +	/**< X9.62 curve over a 239 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_c2pnb272w1,
>> +	/**< X9.62 curve over a 272 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_c2pnb304w1,
>> +	/**< X9.62 curve over a 304 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_c2tnb359v1,
>> +	/**< X9.62 curve over a 359 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_c2pnb368w1,
>> +	/**< X9.62 curve over a 368 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_c2tnb431r1,
>> +	/**< X9.62 curve over a 431 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_wap_wsg_idm_ecid_wtls1,
>> +	/**< WTLS curve over a 113 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_wap_wsg_idm_ecid_wtls3,
>> +	/**< NIST/SECG/WTLS curve over a 163 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_wap_wsg_idm_ecid_wtls4,
>> +	/**< SECG curve over a 113 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_wap_wsg_idm_ecid_wtls5,
>> +	/**< X9.62 curve over a 163 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_wap_wsg_idm_ecid_wtls10,
>> +	/**< NIST/SECG/WTLS curve over a 233 bit binary field */
>> +	RTE_CRYPTO_EC_CURVE_wap_wsg_idm_ecid_wtls11,
>> +	/**< NIST/SECG/WTLS curve over a 233 bit binary field */
>> +	RTE_CRYPTO_EC_BCURVE_LIST_END
>> +};
>[Fiona] Do we really want to specify curves < 224 bits? Even 224 is woefully insecure these days.
>Also do we want to list all "published" curves, or allow customers to specify
>their own curve parameters, at least on the FECC API? Adding an API to specify a curve with
>its params would allow new curves to be used without affecting the API and
>would avoid the need for such an extensive list.
>Do we need a "capabilities" mask to say which curves are supported by a device?
>What about SM2?
>
>> +/**
>> + * Elliptic curve point format
>> + */
>> +struct rte_crypto_ec_point {
>> +	struct {
>> +		int length;
>> +		uint8_t *data;
>> +		phys_addr_t phys_addr;
>> +		/**< phys_addr is used only for points passed in the
>> +		 * asym_op structure.
>> +		 */
>> +	} x;
>> +	/**< X co-ordinate */
>> +
>[Fiona] If generic rte_crypto_param_t is defined then it could be used here too.
>
>> +	struct {
>> +		int length;
>> +		uint8_t *data;
>> +		phys_addr_t phys_addr;
>> +		/**< phys_addr is used only for points passed in the
>> +		 * operation structure
>> +		 */
>> +	} y;
>> +	/**< Y co-ordinate */
>> +};
>> +
>> +/**
>> + * Elliptic curve type
>> + */
>> +enum rte_crypto_ec_curve_type {
>> +	RTE_CRYPTO_EC_CURVE_TYPE_UNDEFINED,
>> +	/**< Curve type undefined */
>> +	RTE_CRYPTO_EC_CURVE_TYPE_PRIME_FIELD,
>> +	/**< EC curve defined over a prime field */
>> +	RTE_CRYPTO_EC_CURVE_TYPE_BINARY_FIELD,
>> +	/**< EC curve defined over a binary field */
>> +	RTE_CRYPTO_EC_CURVE_LIST_END
>> +};
>> +
>> +/** asym xform type name strings */
>> +extern const char *
>> +rte_crypto_asym_xform_strings[];
>> +
>> +/** asym operations type name strings */
>> +extern const char *
>> +rte_crypto_asym_op_strings[];
>> +
>> +/**
>> + * Elliptic curve id
>> + */
>> +struct rte_crypto_ec_curve_id {
>> +	RTE_STD_C11
>> +	union {
>> +		enum rte_crypto_ec_prime_curve pcurve;
>> +		enum rte_crypto_ec_binary_curve bcurve;
>> +	};
>> +};
>[Fiona] Because the values of these two enums overlap, if you specify the curve type incorrectly, you'll still
>have a potentially valid curve enum specified. I suggest it's safer to include the type here with the union,
>rather than in the wrapper xform struct, i.e.
>struct rte_crypto_ec_curve {
>	enum rte_crypto_ec_curve_type curve_type;
>	/**< curve type: Prime vs Binary */
>	union {
>	enum rte_crypto_ec_prime_curve pcurve_id;
>	enum rte_crypto_ec_binary_curve bcurve_id;
>	};
>};
>> +/**
>> + * Asymmetric RSA transform data
>> + *
>> + * This structure contains data required to perform RSA crypto
>> + * transform.
>> + *
>> + */
>> +struct rte_crypto_rsa_xform {
>> +
>> +	rte_crypto_xform_param n;
>> +	/**< n - Prime modulus
>> +	 * Prime modulus data of RSA operation in Octet-string network
>> +	 * byte order format.
>> +	 */
>> +
>> +	rte_crypto_xform_param e;
>> +	/**< e - Public key exponent
>> +	 * Public key exponent used for RSA public key operations in Octet-
>> +	 * string network byte order format.
>> +	 */
>> +
>> +	rte_crypto_xform_param d;
>> +	/**< d - Private key exponent
>> +	 * Private key exponent used for RSA private key operations in
>> +	 * Octet-string  network byte order format.
>> +	 */
>> +
>> +	rte_crypto_xform_param p;
>> +	/**< p - Private key component P
>> +	 * Private key component of RSA parameter  required for CRT method
>> +	 * of private key operations in Octet-string network byte order
>> +	 * format.
>> +	 */
>> +
>> +	rte_crypto_xform_param q;
>> +	/**< q - Private key component Q
>> +	 * Private key component of RSA parameter  required for CRT method
>> +	 * of private key operations in Octet-string network byte order
>> +	 * format.
>> +	 */
>> +
>> +	rte_crypto_xform_param dP;
>> +	/**< dP - Private CRT component
>> +	 * Private CRT component of RSA parameter  required for CRT method
>> +	 * RSA private key operations in Octet-string network byte order
>> +	 * format.
>> +	 * dP = d mod ( p - 1 )
>> +	 */
>> +
>> +	rte_crypto_xform_param dQ;
>> +	/**< dQ - Private CRT component
>> +	 * Private CRT component of RSA parameter  required for CRT method
>> +	 * RSA private key operations in Octet-string network byte order
>> +	 * format.
>> +	 * dQ = d mod ( q - 1 )
>> +	 */
>> +
>> +	rte_crypto_xform_param qInv;
>> +	/**< qInv - Private CRT component
>> +	 * Private CRT component of RSA parameter  required for CRT method
>> +	 * RSA private key operations in Octet-string network byte order
>> +	 * format.
>> +	 * qInv = inv q mod p
>> +	 */
>> +};
>[Fiona] This allows both representations of the private key to be specified
>with the possibility of confusion if both are specified.
>Would it be better to have a union of 2 different structures, one with {n,d} and
>the other with {p,q,dP,dQ,qInv}?
>
>> +/**
>> + * Asymmetric Modular exponentiation transform data
>> + *
>> + * This structure contains data required to perform modular exponentation
>> + * crypto transform.
>> + *
>> + */
>> +struct rte_crypto_modex_xform {
>> +
>> +	rte_crypto_xform_param modulus;
>> +	/**< modulus
>> +	 * Prime modulus of the modexp transform operation in Octet-string
>> +	 * network byte order format.
>> +	 */
>> +
>> +	rte_crypto_xform_param exponent;
>> +	/**< exponent
>> +	 * Private exponent of the modexp transform operation in
>> +	 * Octet-string network byte order format.
>> +	 */
>> +};
>> +
>> +/**
>> + * Asymmetric DH transform data
>> + *
>> + * This structure contains data used to perform DH key
>> + * operations.
>> + *
>> + */
>> +struct rte_crypto_dh_xform {
>> +	rte_crypto_xform_param p;
>> +	/**< p : Prime modulus data
>> +	 * DH prime modulous data in Octet-string network byte order format.
>> +	 */
>> +
>> +	rte_crypto_xform_param g;
>> +	/**< g : Generator
>> +	 * DH group generator data in Octet-string network byte order
>> +	 * format.
>> +	 */
>> +};
>> +
>> +/**
>> + * Asymmetric ECDH transform data
>> + *
>> + * This structure contains data required to perform ECDH crypto
>> + * transform.
>> + *
>> + */
>> +struct rte_crypto_ecdh_xform {
>> +
>> +	enum rte_crypto_ec_curve_type curve_type;
>> +	/**< ECDH curve type: Prime vs Binary */
>> +
>> +	struct rte_crypto_ec_curve_id curve_id;
>> +
>> +	rte_crypto_xform_param p;
>> +	/**< p:
>> +	 * If the curve_type is @ref RTE_CRYPTO_EC_CURVE_TYPE_PRIME_FIELD:
>> +	 * p holds the prime modulus data in Octet string format.
>> +	 *
>> +	 * If the curve_type is @ref RTE_CRYPTO_EC_CURVE_TYPE_BINARY_FIELD:
>> +	 * p holds reduction polynomial co-efficients and degree.
>> +	 */
>> +
>> +	rte_crypto_xform_param a;
>> +	/**< Curve Parameter Co-efficient 'a' of curve equation data in
>> +	 * Octet-string network byte order format.
>> +	 */
>> +
>> +	rte_crypto_xform_param b;
>> +	/**< Curve Parameter Co-efficient 'b' of curve equation data in
>> +	 * Octet-string network byte order format.
>> +	 */
>> +
>> +	struct  rte_crypto_ec_point G;
>> +	/**< G: EC curve generator point
>> +	 * EC curve generator point data in Octet-string network byte order
>> +	 * format.
>> +	 */
>> +
>> +	rte_crypto_xform_param n;
>> +	/**< n : order of G
>> +	 * ECDH curve order data in Octet-string network byte order format.
>> +	 */
>> +
>> +	int h;
>> +	/**< Co-factor of the curve */
>> +
>> +	rte_crypto_xform_param pkey;
>> +	/**< pkey: Private key
>> +	 * Private key data for ECDH operation in Octet-string network byte
>> +	 * order format.
>> +	 */
>> +
>> +	struct rte_crypto_ec_point Q;
>> +	/**< Q: Public key point
>> +	 * Public key point data of ECDH operation in Octet-string network
>> +	 * byte order format.
>> +	 */
>> +};
>> +
>> +/**
>> + * Asymmetric Digital Signature transform operation
>> + *
>> + * This structure contain signer key information for DSA signature
>> + * generation and verification.
>> + * App which does both Signature Generation and Verification should
>> + * create two separate session carrying its own and peer key information
>> + *
>> + */
>> +struct rte_crypto_dsa_xform {
>> +	rte_crypto_xform_param p;
>> +	/**< p - Prime modulus
>> +	 * Prime modulus data for DSA operation in Octet-string network byte
>> +	 * order format.
>> +	 */
>> +	rte_crypto_xform_param q;
>> +	/**< q : Order of the subgroup.
>> +	 * Order of the subgroup data in Octet-string network byte order
>> +	 * format.
>> +	 * (p-1) % q = 0
>> +	 */
>> +	rte_crypto_xform_param g;
>> +	/**< g: Generator of the subgroup
>> +	 * Generator  data in Octet-string network byte order format.
>> +	 */
>> +	rte_crypto_xform_param x;
>> +	/**< x: Private key of the signer
>> +	 * Private key data in Octet-string network byte order format.
>> +	 * Private key is valid only for signature generation operation.
>> +	 */
>> +	rte_crypto_xform_param y;
>> +	/**< y : Public key of the signer.
>> +	 * Public key data of the signer in Octet-string network byte order
>> +	 * format.
>> +	 * y = g^x mod p
>> +	 */
>> +};
>> +
>> +/**
>> + * Asymmetric ECDSA transform data
>> + *
>> + * This structure contains data required to perform ECDSA crypto
>> + * transform.
>> + */
>> +struct rte_crypto_ecdsa_xform {
>> +	/** TBD */
>> +};
>> +
>> +/**
>> + * Asymmetric modular inverse transform operation
>> + *
>> + * This structure contains data required to perform
>> + * asymmetric modular inverse crypto transform
>> + */
>> +struct rte_crypto_modinv_xform {
>> +	/** TBD */
>> +};
>> +
>> +/** Asymmetric Fundamental ECC transform operation
>> + *
>> + * This structure contains data required to perform asymmetric
>> + * fundamental ECC crypto transform.
>> + */
>> +struct rte_crypto_fecc_xform {
>> +
>> +	enum rte_crypto_ec_curve_type curve_type;
>> +	/**< FECC curve type: Prime vs Binary */
>> +
>> +	struct rte_crypto_ec_curve_id curve_id;
>> +	/**< EC curve ID */
>> +
>> +	rte_crypto_xform_param order;
>> +	/**< order : ECC curve order
>> +	 * Curve order data in Octet-string network byte order format.
>> +	 */
>> +
>> +	rte_crypto_xform_param prime;
>> +	/**< prime : Curve prime modulus data
>> +	 * Prime modulus data in Octet-string network byte order format.
>> +	 */
>> +
>> +	struct rte_crypto_ec_point G;
>> +	/**< G: curve generator point
>> +	 * Curve generator point data in Octet-string network byte order
>> +	 * format.
>> +	 */
>> +
>> +	rte_crypto_xform_param a;
>> +	/**< Co-efficient 'a' of curve equation data in Octet-string network
>> +	 * byte order format.
>> +	 */
>> +
>> +	rte_crypto_xform_param b;
>> +	/**< Co-efficient 'a' of curve equation data in Octet-string network
>> +	 * byte order format.
>> +	 */
>> +
>> +	int h;
>> +	/**< Co-factor of the curve */
>> +
>> +};
>> +
>> +/**
>> + * Asymmetric crypto transform data
>> + *
>> + * This structure contains the data required to perform the
>> + * asymmetric crypto transformation operation. The field op
>> + * determines the asymmetric algorithm for transformation.
>[Fiona] clarify comment. The xform only contains some of the data, the rest will be provided in the op.
>And there's no field op here.
>> + */
>> +struct rte_crypto_asym_xform {
>> +	struct rte_crypto_asym_xform *next;
>[Fiona] Is there any reason for a chain of xforms?
>I'd suggest removing unless needed.
>
>> +	enum rte_crypto_asym_xform_type xform_type;
>> +	/**< Asymmetric algorithm for crypto transform */
>> +
>> +	RTE_STD_C11
>> +	union {
>> +		struct rte_crypto_rsa_xform rsa;
>> +		/**< RSA xform parameters */
>> +
>> +		struct rte_crypto_fecc_xform fecc;
>> +		/**< Fundamental Elliptic Curve xform parameters */
>> +
>> +		struct rte_crypto_modex_xform modex;
>> +		/**< Modular Exponentiation xform parameters */
>> +
>> +		struct rte_crypto_modinv_xform modinv;
>> +		/**< Modulus Inverse xform parameters */
>> +
>> +		struct rte_crypto_ecdsa_xform ecdsa;
>> +		/**< ECDSA xform parameters */
>> +
>> +		struct rte_crypto_ecdh_xform ecdh;
>> +		/**< ECDH xform parameters */
>> +
>> +		struct rte_crypto_dsa_xform dsa;
>> +		/**< DSA xform parameters */
>> +	};
>> +};
>> +
>> +struct rte_cryptodev_asym_session;
>> +
>> +/**
>> + * RSA operation params
>> + *
>> + */
>> +struct rte_crypto_rsa_op_param {
>> +	enum rte_crypto_asym_op_type op_type;
>> +	/**< Type of RSA operation for transform */;
>> +
>> +	rte_crypto_op_param message;
>> +	/**<
>> +	 * Pointer to data
>> +	 * - to be encrypted for RSA public encrypt.
>> +	 * - to be decrypted for RSA private decrypt.
>> +	 * - to be signed for RSA sign generation.
>> +	 * - to be authenticated for RSA sign verification.
>> +	 */
>> +
>> +	rte_crypto_op_param sign;
>> +	/**<
>> +	 * Pointer to RSA signature data. If operation is RSA
>> +	 * sign @ref RTE_CRYPTO_RSA_OP_SIGN, buffer will be
>> +	 * over-written with generated signature.
>> +	 *
>> +	 * Length of the signature data will be equal to the
>> +	 * RSA prime modulus length.
>> +	 */
>> +
>> +	enum rte_crypto_rsa_padding_type pad;
>> +	/**< RSA padding scheme to be used for transform */
>> +
>> +	enum rte_crypto_auth_algorithm md;
>> +	/**< Hash algorithm to be used for data hash if padding
>> +	 * scheme is either OAEP or PSS. Valid hash algorithms
>> +	 * are:
>> +	 * MD5, SHA1, SHA224, SHA256, SHA384, SHA512
>> +	 */
>> +
>> +	enum rte_crypto_auth_algorithm mgf1md;
>> +	/**<
>> +	 * Hash algorithm to be used for mask generation if
>> +	 * padding scheme is either OAEP or PSS. If padding
>> +	 * scheme is unspecified data hash algorithm is used
>> +	 * for mask generation. Valid hash algorithms are:
>> +	 * MD5, SHA1, SHA224, SHA256, SHA384, SHA512
>> +	 */
>> +};
>> +
>> +/**
>> + * Deffie-Hellman Operations params
>> + *
>> + */
>> +struct rte_crypto_dh_op_param {
>> +	enum rte_crypto_asym_op_type op_type;
>> +	/**< Asymmetric op type: Key Generation / Computation */
>> +
>> +	rte_crypto_op_param pub_key;
>> +	/**<
>> +	 * Output native app public key when DH operation type is
>> +	 * KEY_GENERATION.
>> +	 * Input peer public key when DH operation is shared key
>> +	 * KEY_COMPUTATION
>> +	 * An Octet-string network byte order format.
>> +	 *
>> +	 */
>> +
>> +	rte_crypto_op_param priv_key;
>> +	/**<
>> +	 * Output native app private key if operation type
>> +	 * KEY_GENERATION.
>> +	 * Input native app private key when operation type
>> +	 * is KEY_COMPUTATION. priv_key is in
>> +	 * in Octet-string network byte order format.
>> +	 */
>> +
>> +	rte_crypto_op_param shared_key;
>> +	/*
>> +	 * Output when DH operation type is KEY_COMPUTATION:
>> +	 * computed. shared_key is written as
>> +	 * Octet-string network byte order format.
>> +	 * Ignored for KEY_GENERATION.
>> +	 */
>> +};
>> +
>> +/**
>> + * DSA Operations params
>> + *
>> + */
>> +struct rte_crypto_dsa_op_param {
>> +	/** TBD */
>> +};
>> +
>> +/**
>> + * Mod Exp Operations params
>> + *
>> + */
>> +struct rte_crypto_modex_op_param {
>> +	rte_crypto_op_param base;
>> +	/**<
>> +	 * Pointer to base of modular exponentiation data in
>> +	 * Octet-string network byte order format.
>> +	 */
>> +};
>> +
>> +/**
>> + * Elliptic curve Deffie-Hellman Operations params
>> + *
>> + */
>> +struct rte_crypto_ecdh_op_param {
>> +	enum rte_crypto_asym_op_type op_type;
>> +	/**< Asymmetric operation: key generation, computation */
>> +
>> +	rte_crypto_op_param priv_key;
>> +	/**<
>> +	 * Output if operation type is KEY_PAIR_GENERATION,
>> +	 * output native app private key.
>> +	 * Input and output, If ECDH operation type is SHARED_KEY_COMPUTATION,
>> +	 * priv_key will hold the 'X' co-ordinate of the shared
>> +	 * secret EC point. priv_key is in Octet-string network
>> +	 * byte order.
>> +	 */
>> +
>> +	struct rte_crypto_ec_point pub_key;
>> +	/**<
>> +	 * Output if operation type is KEY_PAIR_GENERATION,
>> +	 * store native app public key.
>> +	 * Input if operation type is SHARED_KEY_COMPUTATION,
>> +	 *
>> +	 * KEY_COMPUTATION:
>> +	 *  pub_key is in Octet-string network byte order.
>> +	 */
>> +};
>> +
>> +/**
>> + * Elliptic Curve DSA Operations params
>> + *
>> + */
>> +struct rte_crypto_ecdsa_op_param {
>> +
>> +	enum rte_crypto_asym_op_type ecdsa_op;
>> +	/**< ECDSA crypto xform operation type: Signature
>> +	 *  generation/Verification
>> +	 */
>> +	/** TBD */
>> +};
>> +
>> +/**
>> + * Fundamental Elliptic Curve Operations params
>> + *
>> + */
>> +struct rte_crypto_fecc_op_param {
>> +	enum rte_crypto_fecc_optype fecc_op;
>> +	/**< FECC crypto xform operation type */
>> +
>> +	/** TBD */
>> +};
>> +
>> +/**
>> + * Mod Inv Operations params
>> + *
>> + */
>> +struct rte_crypto_modinv_op_param {
>> +	rte_crypto_op_param prime;
>> +	/**<
>> +	 * Pointer to the prime modulus data for modular
>> +	 * inverse operation in Octet-string network byte
>> +	 * order format.
>> +	 */
>> +
>> +	rte_crypto_op_param base;
>> +	/**<
>> +	 * Pointer to the base for the modular inverse
>> +	 * operation in Octet-string network byte order
>> +	 * format.
>> +	 */
>> +};
>> +
>> +/**
>> + * Asymmetric Cryptographic Operation.
>> + *
>> + * This structure contains data relating to performing asymmetric cryptographic
>> + * operation.
>> + *
>> + */
>> +struct rte_crypto_asym_op {
>> +	enum rte_crypto_asym_xform_type type;
>> +	/**< RSA, DH, ECDH, DSA etc */
>> +
>> +	struct rte_cryptodev_asym_session *session;
>> +	/**< Handle for the initialised session context */
>> +
>> +	RTE_STD_C11
>> +	union {
>> +		struct rte_crypto_rsa_op_param rsa;
>> +		struct rte_crypto_dh_op_param dh;
>> +		struct rte_crypto_modex_op_param modex;
>> +		struct rte_crypto_ecdh_op_param ecdh;
>> +		struct rte_crypto_ecdsa_op_param ecdsa;
>> +		struct rte_crypto_dsa_op_param dsa;
>> +		struct rte_crypto_fecc_op_param fecc;
>> +		struct rte_crypto_modinv_op_param modinv;
>> +	};
>> +} __rte_cache_aligned;
>> +
>> +/**
>> + * Reset the fields of an asymmetric operation to their default values.
>> + *
>> + * @param	op	The crypto operation to be reset.
>> + */
>> +static inline void
>> +__rte_crypto_asym_op_reset(struct rte_crypto_asym_op *op)
>> +{
>> +	memset(op, 0, sizeof(*op));
>> +}
>> +
>> +
>> +/**
>> + * Attach a session to an asymmetric crypto operation
>> + *
>> + * @param	asym_op	crypto operation
>> + * @param	sess	cryptodev session
>> + */
>> +static inline int
>> +__rte_crypto_op_attach_asym_session(struct rte_crypto_asym_op *asym_op,
>> +		struct rte_cryptodev_asym_session *sess)
>> +{
>> +	asym_op->session = sess;
>> +	return 0;
>> +}
>> +
>> +#ifdef __cplusplus
>> +}
>> +#endif
>> +
>> +#endif /* _RTE_CRYPTO_ASYM_H_ */
>> diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
>> index 7726d15..bad18c3 100644
>> --- a/lib/librte_cryptodev/rte_cryptodev.c
>> +++ b/lib/librte_cryptodev/rte_cryptodev.c
>> @@ -166,6 +166,33 @@ struct rte_cryptodev_callback {
>>  	[RTE_CRYPTO_AEAD_OP_DECRYPT]	= "decrypt"
>>  };
>>
>> +/**
>> + * Asymmetric crypto transform operation strings identifiers.
>> + */
>> +const char *rte_crypto_asym_xform_strings[] = {
>> +	[RTE_CRYPTO_ASYM_XFORM_RSA]	= "rsa",
>> +	[RTE_CRYPTO_ASYM_XFORM_MODEX]	= "modexp",
>> +	[RTE_CRYPTO_ASYM_XFORM_DH]	= "dh",
>> +	[RTE_CRYPTO_ASYM_XFORM_ECDH]	= "ecdh",
>> +	[RTE_CRYPTO_ASYM_XFORM_DSA]	= "dsa",
>> +	[RTE_CRYPTO_ASYM_XFORM_ECDSA]	= "ecdsa",
>> +	[RTE_CRYPTO_ASYM_XFORM_MODINV]	= "modinv",
>> +	[RTE_CRYPTO_ASYM_XFORM_FECC]	= "fecc"
>> +};
>> +
>> +/**
>> + * Asymmetric crypto operation strings identifiers.
>> + */
>> +const char *rte_crypto_asym_op_strings[] = {
>> +	[RTE_CRYPTO_ASYM_OP_ENCRYPT]	= "encrypt",
>> +	[RTE_CRYPTO_ASYM_OP_DECRYPT]	= "decrypt",
>> +	[RTE_CRYPTO_ASYM_OP_SIGN]	= "sign",
>> +	[RTE_CRYPTO_ASYM_OP_VERIFY]	= "verify",
>> +	[RTE_CRYPTO_ASYM_OP_KEY_PAIR_GENERATION]	= "keypair_generate",
>> +	[RTE_CRYPTO_ASYM_OP_SHARED_KEY_COMPUTATION] = "sharedkey_computation",
>> +	[RTE_CRYPTO_ASYM_OP_ECDH_OP_KEY_CHECK]	= "ecdh_keycheck",
>> +};
>> +
>>  int
>>  rte_cryptodev_get_cipher_algo_enum(enum rte_crypto_cipher_algorithm *algo_enum,
>>  		const char *algo_string)
>> @@ -217,6 +244,24 @@ struct rte_cryptodev_callback {
>>  	return -1;
>>  }
>>
>> +int
>> +rte_cryptodev_get_asym_xform_enum(enum rte_crypto_asym_xform_type *xform_enum,
>> +		const char *xform_string)
>> +{
>> +	unsigned int i;
>> +
>> +	for (i = 1; i < RTE_DIM(rte_crypto_asym_xform_strings); i++) {
>> +		if (strcmp(xform_string,
>> +			   rte_crypto_asym_xform_strings[i]) == 0) {
>> +			*xform_enum = (enum rte_crypto_asym_xform_type) i;
>> +			return 0;
>> +		}
>> +	}
>> +
>> +	/* Invalid string */
>> +	return -1;
>> +}
>> +
>>  /**
>>   * The crypto auth operation strings identifiers.
>>   * It could be used in application command line.
>> @@ -262,6 +307,28 @@ struct rte_cryptodev_callback {
>>
>>  }
>>
>> +const struct rte_cryptodev_asymmetric_capability *
>> +rte_cryptodev_asym_capability_get(uint8_t dev_id,
>> +		const struct rte_cryptodev_asym_capability_idx *idx)
>> +{
>> +	const struct rte_cryptodev_capabilities *capability;
>> +	struct rte_cryptodev_info dev_info;
>> +	unsigned int i = 0;
>> +
>> +	memset(&dev_info, 0, sizeof(rte_cryptodev_info));
>> +	rte_cryptodev_info_get(dev_id, &dev_info);
>> +
>> +	while ((capability = &dev_info.capabilities[i++])->op !=
>> +			RTE_CRYPTO_OP_TYPE_UNDEFINED) {
>> +		if (capability->op != RTE_CRYPTO_OP_TYPE_ASYMMETRIC)
>> +			continue;
>> +
>> +		if (capability->asym.xform_type == idx->type)
>> +			return &capability->asym;
>> +	}
>> +	return NULL;
>> +};
>> +
>>  #define param_range_check(x, y) \
>>  	(((x < y.min) || (x > y.max)) || \
>>  	(y.increment != 0 && (x % y.increment) != 0))
>> @@ -601,6 +668,24 @@ struct rte_cryptodev *
>>  	return dev->data->nb_queue_pairs;
>>  }
>>
>> +uint16_t
>> +rte_cryptodev_asym_queue_pair_count(uint8_t dev_id)
>> +{
>> +	struct rte_cryptodev *dev;
>> +
>> +	dev = &rte_crypto_devices[dev_id];
>> +	return dev->data->nb_asym_qp;
>> +}
>> +
>> +uint16_t
>> +rte_cryptodev_sym_queue_pair_count(uint8_t dev_id)
>> +{
>> +	struct rte_cryptodev *dev;
>> +
>> +	dev = &rte_crypto_devices[dev_id];
>> +	return dev->data->nb_sym_qp;
>> +}
>> +
>>  static int
>>  rte_cryptodev_queue_pairs_config(struct rte_cryptodev *dev, uint16_t nb_qpairs,
>>  		int socket_id)
>> @@ -1088,6 +1173,38 @@ struct rte_cryptodev *
>>  	return 0;
>>  }
>>
>> +int
>> +rte_cryptodev_asym_session_init(uint8_t dev_id,
>> +		struct rte_cryptodev_asym_session *sess,
>> +		struct rte_crypto_asym_xform *xforms,
>> +		struct rte_mempool *mp)
>> +{
>> +	struct rte_cryptodev *dev;
>> +	uint8_t index;
>> +	int ret;
>> +
>> +	dev = rte_cryptodev_pmd_get_dev(dev_id);
>> +
>> +	if (sess == NULL || xforms == NULL || dev == NULL)
>> +		return -EINVAL;
>> +
>> +	index = dev->driver_id;
>> +
>> +	if (sess->sess_private_data[index] == NULL) {
>> +		ret = dev->dev_ops->asym_session_configure(dev,
>> +							   xforms,
>> +							   sess, mp);
>> +		if (ret < 0) {
>> +			CDEV_LOG_ERR(
>> +				"dev_id %d failed to configure session details",
>> +				dev_id);
>> +			return ret;
>> +		}
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>>  struct rte_cryptodev_sym_session *
>>  rte_cryptodev_sym_session_create(struct rte_mempool *mp)
>>  {
>> @@ -1105,6 +1222,23 @@ struct rte_cryptodev_sym_session *
>>  	return sess;
>>  }
>>
>> +struct rte_cryptodev_asym_session *
>> +rte_cryptodev_asym_session_create(struct rte_mempool *mp)
>> +{
>> +	struct rte_cryptodev_asym_session *sess;
>> +
>> +	/* Allocate a session structure from the session pool */
>> +	if (rte_mempool_get(mp, (void *)&sess)) {
>> +		CDEV_LOG_ERR("couldn't get object from session mempool");
>> +		return NULL;
>> +	}
>> +
>> +	/* Clear device session pointer */
>> +	memset(sess, 0, (sizeof(void *) * nb_drivers));
>> +
>> +	return sess;
>> +}
>> +
>>  int
>>  rte_cryptodev_queue_pair_attach_sym_session(uint8_t dev_id, uint16_t qp_id,
>>  		struct rte_cryptodev_sym_session *sess)
>> @@ -1160,6 +1294,60 @@ struct rte_cryptodev_sym_session *
>>  }
>>
>>  int
>> +rte_cryptodev_queue_pair_attach_asym_session(uint8_t dev_id, uint16_t qp_id,
>> +		struct rte_cryptodev_asym_session *sess)
>> +{
>> +	struct rte_cryptodev *dev;
>> +
>> +	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
>> +		CDEV_LOG_ERR("Invalid dev_id=%d", dev_id);
>> +		return -EINVAL;
>> +	}
>> +
>> +	dev = &rte_crypto_devices[dev_id];
>> +
>> +	/* The API is optional, not returning error if driver do not suuport */
>> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->asym_qp_attach_session, 0);
>> +
>> +	void *sess_priv = get_asym_session_private_data(sess, dev->driver_id);
>> +
>> +	if (dev->dev_ops->asym_qp_attach_session(dev, qp_id, sess_priv)) {
>> +		CDEV_LOG_ERR("dev_id %d failed to attach qp: %d with session",
>> +				dev_id, qp_id);
>> +		return -EPERM;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +int
>> +rte_cryptodev_queue_pair_detach_asym_session(uint8_t dev_id, uint16_t qp_id,
>> +		struct rte_cryptodev_asym_session *sess)
>> +{
>> +	struct rte_cryptodev *dev;
>> +
>> +	if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
>> +		CDEV_LOG_ERR("Invalid dev_id=%d", dev_id);
>> +		return -EINVAL;
>> +	}
>> +
>> +	dev = &rte_crypto_devices[dev_id];
>> +
>> +	/* The API is optional, not returning error if driver do not suuport */
>> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->asym_qp_detach_session, 0);
>> +
>> +	void *sess_priv = get_asym_session_private_data(sess, dev->driver_id);
>> +
>> +	if (dev->dev_ops->asym_qp_detach_session(dev, qp_id, sess_priv)) {
>> +		CDEV_LOG_ERR("dev_id %d failed to detach qp: %d from session",
>> +				dev_id, qp_id);
>> +		return -EPERM;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +int
>>  rte_cryptodev_sym_session_clear(uint8_t dev_id,
>>  		struct rte_cryptodev_sym_session *sess)
>>  {
>> @@ -1176,6 +1364,22 @@ struct rte_cryptodev_sym_session *
>>  }
>>
>>  int
>> +rte_cryptodev_asym_session_clear(uint8_t dev_id,
>> +		struct rte_cryptodev_asym_session *sess)
>> +{
>> +	struct rte_cryptodev *dev;
>> +
>> +	dev = rte_cryptodev_pmd_get_dev(dev_id);
>> +
>> +	if (dev == NULL || sess == NULL)
>> +		return -EINVAL;
>> +
>> +	dev->dev_ops->asym_session_clear(dev, sess);
>> +
>> +	return 0;
>> +}
>> +
>> +int
>>  rte_cryptodev_sym_session_free(struct rte_cryptodev_sym_session *sess)
>>  {
>>  	uint8_t i;
>> @@ -1199,6 +1403,31 @@ struct rte_cryptodev_sym_session *
>>  	return 0;
>>  }
>>
>> +int
>> +rte_cryptodev_asym_session_free(struct rte_cryptodev_asym_session *sess)
>> +{
>> +	uint8_t i;
>> +	void *sess_priv;
>> +	struct rte_mempool *sess_mp;
>> +
>> +	if (sess == NULL)
>> +		return -EINVAL;
>> +
>> +	/* Check that all device private data has been freed */
>> +	for (i = 0; i < nb_drivers; i++) {
>> +		sess_priv = get_asym_session_private_data(sess, i);
>> +		if (sess_priv != NULL)
>> +			return -EBUSY;
>> +	}
>> +
>> +	/* Return session to mempool */
>> +	sess_mp = rte_mempool_from_obj(sess);
>> +	rte_mempool_put(sess_mp, sess);
>> +
>> +	return 0;
>> +}
>> +
>> +
>>  unsigned int
>>  rte_cryptodev_get_header_session_size(void)
>>  {
>> @@ -1235,6 +1464,57 @@ struct rte_cryptodev_sym_session *
>>  		return header_size;
>>
>>  	return priv_sess_size;
>> +}
>> +
>> +unsigned int
>> +rte_cryptodev_get_sym_session_private_size(uint8_t dev_id)
>> +{
>> +	struct rte_cryptodev *dev;
>> +	unsigned int header_size = sizeof(void *) * nb_drivers;
>> +	unsigned int priv_sess_size;
>> +
>> +	if (!rte_cryptodev_pmd_is_valid_dev(dev_id))
>> +		return 0;
>> +
>> +	dev = rte_cryptodev_pmd_get_dev(dev_id);
>> +
>> +	if (*dev->dev_ops->sym_session_get_size == NULL)
>> +		return 0;
>> +
>> +	priv_sess_size = (*dev->dev_ops->sym_session_get_size)(dev);
>> +
>> +	/*
>> +	 * If size is less than session header size,
>> +	 * return the latter, as this guarantees that
>> +	 * sessionless operations will work
>> +	 */
>> +	if (priv_sess_size < header_size)
>> +		return header_size;
>> +
>> +	return priv_sess_size;
>> +}
>> +
>> +
>> +unsigned int
>> +rte_cryptodev_get_asym_session_private_size(uint8_t dev_id)
>> +{
>> +	struct rte_cryptodev *dev;
>> +	unsigned int header_size = sizeof(void *) * nb_drivers;
>> +	unsigned int priv_sess_size;
>> +
>> +	if (!rte_cryptodev_pmd_is_valid_dev(dev_id))
>> +		return 0;
>> +
>> +	dev = rte_cryptodev_pmd_get_dev(dev_id);
>> +
>> +	if (*dev->dev_ops->asym_session_get_size == NULL)
>> +		return 0;
>> +
>> +	priv_sess_size = (*dev->dev_ops->asym_session_get_size)(dev);
>> +	if (priv_sess_size < header_size)
>> +		return header_size;
>> +
>> +	return priv_sess_size;
>>
>>  }
>>
>> @@ -1268,6 +1548,13 @@ struct rte_mempool *
>>  			sizeof(struct rte_crypto_sym_op) +
>>  			priv_size;
>>
>> +	if (type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
>> +		/* override size by size of asym op */
>> +		elt_size = sizeof(struct rte_crypto_op) +
>> +			   sizeof(struct rte_crypto_asym_op) +
>> +			   priv_size;
>> +	}
>> +
>>  	/* lookup mempool in case already allocated */
>>  	struct rte_mempool *mp = rte_mempool_lookup(name);
>>
>> diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
>> index c8fa689..728483c 100644
>> --- a/lib/librte_cryptodev/rte_cryptodev.h
>> +++ b/lib/librte_cryptodev/rte_cryptodev.h
>> @@ -178,15 +178,41 @@ struct rte_cryptodev_symmetric_capability {
>>  	};
>>  };
>>
>> +/**
>> + * Asymmetric Crypto Capability
>> + *
>> + */
>> +struct rte_cryptodev_asymmetric_capability {
>> +	enum rte_crypto_asym_xform_type xform_type;
>> +	/**< Transform type: RSA/MODEXP/DH/ECDH/DSA/ECDSA/FECC/MODINV */
>> +
>[Fiona] Is there a fixed set of rte_cryptodev_asym_op_type for each xform type?
>If any variant possible then there would need to be a capability field for this.
>
>	RTE_STD_C11
>> +	union {
>> +		struct rte_crypto_param_range modlen;
>> +		/**< Range of modulus length supported for modulus based
>> +		 * algos:
>> +		 * RSA
>> +		 * MODEXP
>> +		 * MODINV
>> +		 * DH
>> +		 *
>> +		 * Value 0 to min and/or max means no specific limit and limit
>> +		 * is implementation dependent
>> +		 *
>> +		 */
>> +	};
>> +};
>> +
>>  /** Structure used to capture a capability of a crypto device */
>>  struct rte_cryptodev_capabilities {
>>  	enum rte_crypto_op_type op;
>> -	/**< Operation type */
>> +	/**< Operation type: symmetric/asymmetric */
>>
>>  	RTE_STD_C11
>>  	union {
>>  		struct rte_cryptodev_symmetric_capability sym;
>>  		/**< Symmetric operation capability parameters */
>> +		struct rte_cryptodev_asymmetric_capability asym;
>> +		/**< Asymmetric operation capability parameters */
>>  	};
>>  };
>>
>> @@ -201,7 +227,17 @@ struct rte_cryptodev_sym_capability_idx {
>>  };
>>
>>  /**
>> - *  Provide capabilities available for defined device and algorithm
>> + * Structure used to describe asymmetric crypto xforms
>> + * Each xform maps to one asym algorithm.
>> + *
>> + */
>> +struct rte_cryptodev_asym_capability_idx {
>> +	enum rte_crypto_asym_xform_type type;
>> +	/**< Asymmetric xform (algo) type */
>> +};
>> +
>> +/**
>> + * Provide capabilities available for defined device and algorithm
>>   *
>>   * @param	dev_id		The identifier of the device.
>>   * @param	idx		Description of crypto algorithms.
>> @@ -215,6 +251,20 @@ struct rte_cryptodev_sym_capability_idx {
>>  		const struct rte_cryptodev_sym_capability_idx *idx);
>>
>>  /**
>> + *  Provide capabilities available for defined device and algorithm
>> + *
>> + * @param	dev_id		The identifier of the device.
>> + * @param	algo		Description of crypto algorithms.
>> + *
>> + * @return
>> + *   - Return description of the asymmetric crypto capability if exist.
>> + *   - Return NULL if the capability not exist.
>> + */
>> +const struct rte_cryptodev_asymmetric_capability *
>> +rte_cryptodev_asym_capability_get(uint8_t dev_id,
>> +		const struct rte_cryptodev_asym_capability_idx *idx);
>> +
>> +/**
>>   * Check if key size and initial vector are supported
>>   * in crypto cipher capability
>>   *
>> @@ -270,6 +320,21 @@ struct rte_cryptodev_sym_capability_idx {
>>  		uint16_t iv_size);
>>
>>  /**
>> + * Check if modulus length is in supported range
>> + *
>> + * @param	capability	Description of the asymmetric crypto capability.
>> + * @param	modlen		modulus length.
>> + *
>> + * @return
>> + *   - Return 0 if the parameters are in range of the capability.
>> + *   - Return -1 if the parameters are out of range of the capability.
>> + */
>> +int
>> +rte_cryptodev_asym_capability_check_modlen(
>> +		const struct rte_cryptodev_asymmetric_capability *capability,
>> +		uint16_t modlen);
>> +
>> +/**
>>   * Provide the cipher algorithm enum, given an algorithm string
>>   *
>>   * @param	algo_enum	A pointer to the cipher algorithm
>> @@ -314,6 +379,22 @@ struct rte_cryptodev_sym_capability_idx {
>>  rte_cryptodev_get_aead_algo_enum(enum rte_crypto_aead_algorithm *algo_enum,
>>  		const char *algo_string);
>>
>> +/**
>> + * Provide the Asymmetric xform enum, given an xform string
>> + *
>> + * @param	xform_enum	A pointer to the xform type
>> + *				enum to be filled
>> + * @param	xform_string	xform string
>> + *
>> + * @return
>> + * - Return -1 if string is not valid
>> + * - Return 0 is the string is valid
>> + */
>> +int
>> +rte_cryptodev_get_asym_xform_enum(enum rte_crypto_asym_xform_type *xform_enum,
>> +		const char *xform_string);
>> +
>> +
>>  /** Macro used at end of crypto PMD list */
>>  #define RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() \
>>  	{ RTE_CRYPTO_OP_TYPE_UNDEFINED }
>> @@ -379,16 +460,99 @@ struct rte_cryptodev_info {
>>  	/**< Array of devices supported capabilities */
>>
>>  	unsigned max_nb_queue_pairs;
>> -	/**< Maximum number of queues pairs supported by device. */
>> +	/**< Maximum number of queues pairs supported by device.
>> +	 *
>> +	 * This is total number of queues supported by device and inclusive
>> +	 * of numbers used for both symmetric and asymmetric for PMD that
>> +	 * support symmetric and asymmetric op i.e.
>> +	 *
>> +	 * max_nb_queue_pairs = max_nb_symm_qp + max_nb_asymm_qp
>> +	 *
>> +	 * Following table demonstarte what the values should be for device
>> +	 * with max num of 'n' queue pair (x = don't care):
>> +	 *
>> +	 *  -------------------------------------------------------------------
>> +	 * |dev_capa                | max_nb_asymm_qp| max_nb_symm_qp | max_qp|
>> +	 *  -------------------------------------------------------------------
>> +	 * | Symm only              |    x           | 0              | n     |
>> +	 * | Asymm only             |    0           | x              | n     |
>> +	 * | symm+asymm w/ fixed qp |    p           | n-p            | n     |
>> +	 * | symm+asymm w/ all qp   |    0           | 0              | n     |
>> +	 *  -------------------------------------------------------------------
>> +	 *
>> +	 * - if device supports only asymmetric, then max_nb_queue_pair
>> +	 *   indicates max qp available for asymmetric operations.
>> +	 *
>> +	 * - if device support only symmetric, then max_nb_queue_pair
>> +	 *   indicates max qp available for symmetric operations.
>> +	 *
>> +	 * - if device support both symmetric and asymmetric crypto op,
>> +	 *   then max_nb_queue_pair indicates total number of available
>> +	 *   qp for both operations.
>> +	 *
>> +	 * **Special note on devices supporting symm and asymm:
>> +	 *
>> +	 * Such dual function devices may manage qp in various possible ways.
>> +	 * They can either:
>> +	 *
>> +	 * 1. Use all max_nb_queue_pair for any operation type.
>> +	 *    In such case, app can configure any of the available qp
>> +	 *    for any operaiton. Thus,
>> +	 *    dev_info should return num queue pair distribution as mentioned
>> +	 *    in row 'symm+asymm w/ all qp' in table above
>> +	 *
>> +	 * 2. Or, use dedicated set of qp for each op
>> +	 *    Such device PMDs, can take 2 approaches:
>> +	 *    1. Either, it can show up as 2 separate PMDs where one as
>> +	 *	 symmetric only and other asymmetric only. in such case,
>> +	 *	 device info will return num queue pair distribution as
>> +	 *	 mentioned in row 'symmetric/asymmetric only' device
>> +	 *
>> +	 *    2. Or, can appear as one PMD with number of queue pair dedicated
>> +	 *	 to each operation in max_nb_symm_qp and max_nb_asymm_qp
>> +	 *
>> +	 */
>>
>>  	struct {
>>  		unsigned max_nb_sessions;
>> -		/**< Maximum number of sessions supported by device. */
>> +		/**< Maximum number of sessions supported
>> +		 * for symmetric operations.
>> +		 */
>>  		unsigned int max_nb_sessions_per_qp;
>> -		/**< Maximum number of sessions per queue pair.
>> +		/**< Maximum number of symmetric sessions
>> +		 * per queue pair.
>>  		 * Default 0 for infinite sessions
>>  		 */
>> +		 unsigned int max_nb_sym_qp;
>> +		/**< Maximum num of qp dedicated to symmetric op.
>> +		 * NA for device that support symmetric only.
>> +		 * 0 means device can use all max_nb_queue_pair
>> +		 * for symm op.
>> +		 * Please note, this variable only tells number of queue pairs
>> +		 * that can be enqueued with symmetric ops and doesn't reveal
>> +		 * specific IDs used by PMDs for this operation
>> +		 *
>> +		 */
>>  	} sym;
>> +
>> +	struct {
>> +		unsigned int max_nb_asym_sessions;
>> +		/**< Maximum number of asymmetric sessions supported by device.
>> +		 * 0 infinite as long as resources are available
>> +		 */
>> +		unsigned int max_nb_asym_sessions_per_qp;
>> +		/**< Maximum number of asymmetric sessions per queue pair.
>> +		 * 0 means infinite as long as resources are available
>> +		 */
>> +		unsigned int max_nb_asym_qp;
>> +		/**< Maximum number of qp dedicated for asymm operation.
>> +		 * 0 means device can use all max_nb_queue_pair for asymm op.
>> +		 * Please note, this variable only tells number of queue pairs
>> +		 * that can be enqueued with asymmetric ops and doesn't reveal
>> +		 * specific IDs used by PMDs for this operation
>> +		 *
>> +		 */
>> +	} asym;
>>  };
>>
>>  #define RTE_CRYPTODEV_DETACHED  (0)
>> @@ -513,6 +677,24 @@ struct rte_cryptodev_config {
>>  	int socket_id;			/**< Socket to allocate resources on */
>>  	uint16_t nb_queue_pairs;
>>  	/**< Number of queue pairs to configure on device */
>> +
>> +	uint16_t nb_symm_qp;
>> +	/**< Number of queue pair to be used for symmetric operations.
>> +	 * Optional input.
>> +	 * Valid for device supporting both symmetric and asymmetric.
>> +	 * Should be less than equal to rte_cryptodev_info:max_nb_symm_qp.
>> +	 * please note this number only tells how many queue pair to be used
>> +	 * for symmetric op and does *not* tell specific IDs to be used.
>> +	 */
>> +
>> +	uint16_t nb_asymm_qp;
>> +	/**< Number of queue pair to be used for asymmetric operations.
>> +	 * Optional input.
>> +	 * Valid for device supporting both asymmetric and symmetric.
>> +	 * Should be less than equal to rte_cryptodev_info:max_nb_asymm_qp
>> +	 * Please note this number only tells how many queue pair to be
>> +	 * used for asymmetric and does *not* specifically tell qp ID
>> +	 */
>>  };
>>
>[Fiona] The params from config structure above should be used to set the values in the data structure
>This code is missing.
>
>>  /**
>> @@ -595,6 +777,9 @@ struct rte_cryptodev_config {
>>   * @return
>>   *   - 0: Success, queue pair correctly set up.
>>   *   - <0: Queue pair configuration failed
>> + *
>> + * @note: queue pair to be setup independent of operation type.
>> + *
>>   */
>>  extern int
>>  rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
>> @@ -644,6 +829,26 @@ struct rte_cryptodev_config {
>>  extern uint16_t
>>  rte_cryptodev_queue_pair_count(uint8_t dev_id);
>>
>> +/**
>> + * Get the number of symmetric queue pairs on this crypto device
>> + *
>> + * @param	dev_id		Crypto device identifier.
>> + * @return
>> + *   - The number of configured symmetric queue pairs.
>> + */
>> +extern uint16_t
>> +rte_cryptodev_sym_queue_pair_count(uint8_t dev_id);
>> +
>> +
>> +/**
>> + * Get the number of asymmetric queue pairs on this crypto device
>> + *
>> + * @param	dev_id		Crypto device identifier.
>> + * @return
>> + *   - The number of configured asymmetric queue pairs.
>> + */
>> +extern uint16_t
>> +rte_cryptodev_asym_queue_pair_count(uint8_t dev_id);
>>
>>  /**
>>   * Retrieve the general I/O statistics of a device.
>> @@ -795,6 +1000,10 @@ struct rte_cryptodev_data {
>>  	/**< Array of pointers to queue pairs. */
>>  	uint16_t nb_queue_pairs;
>>  	/**< Number of device queue pairs. */
>> +	uint16_t nb_sym_qp;
>> +	/**< Number of symmetric queue pairs. */
>> +	uint16_t nb_asym_qp;
>> +	/**< Number of asymmetric queue pairs. */
>>
>>  	void *dev_private;
>>  	/**< PMD-specific private data */
>> @@ -900,6 +1109,11 @@ struct rte_cryptodev_sym_session {
>>  	/**< Private session material */
>>  };
>>
>> +/** Cryptodev asymmetric crypto session */
>> +struct rte_cryptodev_asym_session {
>> +	__extension__ void *sess_private_data[0];
>> +	/**< Private asymmetric session material */
>> +};
>>
>>  /**
>>   * Create symmetric crypto session header (generic with no private data)
>> @@ -914,6 +1128,18 @@ struct rte_cryptodev_sym_session *
>>  rte_cryptodev_sym_session_create(struct rte_mempool *mempool);
>>
>>  /**
>> + * Create asymmetric crypto session header (generic with no private data)
>> + *
>> + * @param   mempool    mempool to allocate asymmetric session
>> + *                     objects from
>> + * @return
>> + *  - On success return pointer to asym-session
>> + *  - On failure returns NULL
>> + */
>> +struct rte_cryptodev_asym_session *
>> +rte_cryptodev_asym_session_create(struct rte_mempool *mempool);
>> +
>> +/**
>>   * Frees symmetric crypto session header, after checking that all
>>   * the device private data has been freed, returning it
>>   * to its original mempool.
>> @@ -929,6 +1155,21 @@ struct rte_cryptodev_sym_session *
>>  rte_cryptodev_sym_session_free(struct rte_cryptodev_sym_session *sess);
>>
>>  /**
>> + * Frees asymmetric crypto session header, after checking that all
>> + * the device private data has been freed, returning it
>> + * to its original mempool.
>> + *
>> + * @param   sess     Session header to be freed.
>> + *
>> + * @return
>> + *  - 0 if successful.
>> + *  - -EINVAL if session is NULL.
>> + *  - -EBUSY if not all device private data has been freed.
>> + */
>> +int
>> +rte_cryptodev_asym_session_free(struct rte_cryptodev_asym_session *sess);
>> +
>> +/**
>>   * Fill out private data for the device id, based on its device type.
>>   *
>>   * @param   dev_id   ID of device that we want the session to be used on
>> @@ -950,6 +1191,27 @@ struct rte_cryptodev_sym_session *
>>  			struct rte_mempool *mempool);
>>
>>  /**
>> + * Initialize asymmetric session on a device with specific asymmetric xform
>> + *
>> + * @param   dev_id   ID of device that we want the session to be used on
>> + * @param   sess     Session to be set up on a device
>> + * @param   xforms   Asymmetric crypto transform operations to apply on flow
>> + *                   processed with this session
>> + * @param   mempool  Mempool to be used for internal allocation.
>> + *
>> + * @return
>> + *  - On success, zero.
>> + *  - -EINVAL if input parameters are invalid.
>> + *  - -ENOTSUP if crypto device does not support the crypto transform.
>> + *  - -ENOMEM if the private session could not be allocated.
>> + */
>> +int
>> +rte_cryptodev_asym_session_init(uint8_t dev_id,
>> +			struct rte_cryptodev_asym_session *sess,
>> +			struct rte_crypto_asym_xform *xforms,
>> +			struct rte_mempool *mempool);
>> +
>> +/**
>>   * Frees private data for the device id, based on its device type,
>>   * returning it to its mempool.
>>   *
>> @@ -965,7 +1227,23 @@ struct rte_cryptodev_sym_session *
>>  			struct rte_cryptodev_sym_session *sess);
>>
>>  /**
>> + * Frees resources held by asymmetric session during rte_cryptodev_session_init
>> + *
>> + * @param   dev_id   ID of device that uses the asymmetric session.
>> + * @param   sess     Asymmetric session setup on device using
>> + *					 rte_cryptodev_session_init
>> + * @return
>> + *  - 0 if successful.
>> + *  - -EINVAL if device is invalid or session is NULL.
>> + */
>> +int
>> +rte_cryptodev_asym_session_clear(uint8_t dev_id,
>> +			struct rte_cryptodev_asym_session *sess);
>> +
>> +/**
>>   * Get the size of the header session, for all registered drivers.
>> + * For devices supporting both symmetric and asymmetric, it should
>> + * return header size inclusive of both
>[Fiona] ? This API is not called on a device.
>As the hdr size is just a list of pointers, it's independent of sym/asym
>
>>   *
>>   * @return
>>   *   Size of the header session.
>> @@ -975,6 +1253,8 @@ struct rte_cryptodev_sym_session *
>>
>>  /**
>>   * Get the size of the private session data for a device.
>> + * if device support both symmetric and asymmetric, it
>> + * return size inclusive of both
>[Fiona] Are you suggesting the same session pool might be used
>for both sym and asym sessions?
>Seems unlikely, but if an application chose to, it seems better
> that it would do it explicitly,
>e.g. get asym and sym private sizes, same as it gets size from the other
>drivers and sizes for the maximum.
>If meaning is changed as you suggest then sym applications already
>implemented will likely end up with pools sized for a session size they don’t need.
>
>As I think the combined pool case unlikely, it makes more sense to me that this
>fn should have comment changed to say it returns only sym session size
>for backwards capability reasons, but will be deprecated
>and appls should use get_sym_session_private_size instead.
>
>>   *
>>   * @param	dev_id		The device identifier.
>>   *
>> @@ -986,6 +1266,32 @@ struct rte_cryptodev_sym_session *
>>  rte_cryptodev_get_private_session_size(uint8_t dev_id);
>>
>>  /**
>> + * Get the size of the private data for symmetric session
>> + * on device
>> + *
>> + * @param	dev_id		The device identifier.
>> + *
>> + * @return
>> + *   - Size of the symmetric session private data, if successful
>> + *   - 0 if device is invalid or does not have private session
>> + */
>> +unsigned int
>> +rte_cryptodev_get_sym_session_private_size(uint8_t dev_id);
>> +
>> +/**
>> + * Get the size of the private data for asymmetric session
>> + * on device
>> + *
>> + * @param	dev_id		The device identifier.
>> + *
>> + * @return
>> + *   - Size of the asymmetric private data, if successful
>> + *   - 0 if device is invalid or does not have private session
>> + */
>> +unsigned int
>> +rte_cryptodev_get_asym_session_private_size(uint8_t dev_id);
>> +
>> +/**
>>   * Attach queue pair with sym session.
>>   *
>>   * @param	dev_id		Device to which the session will be attached.
>> @@ -1002,6 +1308,31 @@ struct rte_cryptodev_sym_session *
>>  		struct rte_cryptodev_sym_session *session);
>>
>>  /**
>> + * Attach queue pair with asym session.
>> + *
>> + * @param	dev_id		Device to which the session is attached.
>> + * @param	qp_id		Queue pair to which the session will be
>> + *				attached.
>> + * @param	session		Asymmetric Session pointer previously
>> + *				allocated by
>> + *				*rte_cryptodev_asym_session_create*.
>> + *
>> + * @return
>> + *  - On success, zero.
>> + *  - On failure, a negative value.
>> + *
>> + * @note : app can dedicate a qp_id to specific operation type:symm/asymm
>> + * by calling rte_cryptodev_queue_pair_attach_sym/asym_session() before
>> + * enqueue_burst() call. PMD with SYMMETRIC & ASYMMETRIC feature flag set,
>> + * can internally bind the logical qp_id to actual physical qp_id here and
>> + * dedicate specific qp_id to perform specific op_type(symmetric or
>> + * asymmetric).
>> + */
>> +int
>> +rte_cryptodev_queue_pair_attach_asym_session(uint8_t dev_id, uint16_t qp_id,
>> +		struct rte_cryptodev_asym_session *session);
>> +
>> +/**
>>   * Detach queue pair with sym session.
>>   *
>>   * @param	dev_id		Device to which the session is attached.
>> @@ -1018,6 +1349,23 @@ struct rte_cryptodev_sym_session *
>>  		struct rte_cryptodev_sym_session *session);
>>
>>  /**
>> + * Detach queue pair from asym session.
>> + *
>> + * @param	dev_id		Device to which the session is attached.
>> + * @param	qp_id		Queue pair to which the session is attached.
>> + * @param	session		Asymmetric Session pointer previously attached
>> + *				by calling
>> + *				*rte_cryptodev_queue_pair_attach_asym_session*.
>> + *
>> + * @return
>> + *  - On success, zero.
>> + *  - On failure, a negative value.
>> + */
>> +int
>> +rte_cryptodev_queue_pair_detach_asym_session(uint8_t dev_id, uint16_t qp_id,
>> +		struct rte_cryptodev_asym_session *session);
>> +
>> +/**
>>   * Provide driver identifier.
>>   *
>>   * @param name
>> diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.c b/lib/librte_cryptodev/rte_cryptodev_pmd.c
>> index f2aac24..4439a8e 100644
>> --- a/lib/librte_cryptodev/rte_cryptodev_pmd.c
>> +++ b/lib/librte_cryptodev/rte_cryptodev_pmd.c
>> @@ -66,6 +66,20 @@
>>  			goto free_kvlist;
>>
>>  		ret = rte_kvargs_process(kvlist,
>> +				RTE_CRYPTODEV_PMD_MAX_NB_ASYM_QP_ARG,
>> +				&rte_cryptodev_pmd_parse_uint_arg,
>> +				&params->max_nb_asym_qp);
>> +		if (ret < 0)
>> +			goto free_kvlist;
>> +
>> +		ret = rte_kvargs_process(kvlist,
>> +				RTE_CRYPTODEV_PMD_MAX_NB_SYM_QP_ARG,
>> +				&rte_cryptodev_pmd_parse_uint_arg,
>> +				&params->max_nb_sym_qp);
>> +		if (ret < 0)
>> +			goto free_kvlist;
>> +
>[Fiona] "max_nb_queue_pair" is passed in to args and parsed. Stored in init_params,
>passed to device creation. And then ignored, not used at all. So no need to add new
>max_nb_asym_qp and max_nb_sym_qp to either args or init_params. They're not
>used either in this RFC.
>We should deprecate the current param from args and init_params.
>
>PMDs hardcode the value they return in rte_cryptodev_info.
>> +		ret = rte_kvargs_process(kvlist,
>>  				RTE_CRYPTODEV_PMD_MAX_NB_SESS_ARG,
>>  				&rte_cryptodev_pmd_parse_uint_arg,
>>  				&params->max_nb_sessions);
>> @@ -109,9 +123,12 @@ struct rte_cryptodev *
>>  			device->driver->name, name);
>>
>>  	CDEV_LOG_INFO("[%s] - Initialisation parameters - name: %s,"
>> -			"socket id: %d, max queue pairs: %u, max sessions: %u",
>> +			"socket id: %d, max queue pairs: %u, "
>> +			"max sym queue paid: %u, max asym queue pair %u, "
>> +			"max sessions: %u",
>>  			device->driver->name, name,
>>  			params->socket_id, params->max_nb_queue_pairs,
>> +			params->max_nb_asym_qp, params->max_nb_sym_qp,
>>  			params->max_nb_sessions);
>>
>>  	/* allocate device structure */
>> diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
>> index 089848e..272b489 100644
>> --- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
>> +++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
>> @@ -60,18 +60,25 @@
>>
>>  #define RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS	8
>>  #define RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SESSIONS	2048
>> +/* Allow all qp to be used for sym */
>> +#define RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_SYM_QP		0
>> +/* Allow all qp to be used for asym */
>> +#define RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_ASYM_QP	0
>>
>>  #define RTE_CRYPTODEV_PMD_NAME_ARG			("name")
>>  #define RTE_CRYPTODEV_PMD_MAX_NB_QP_ARG			("max_nb_queue_pairs")
>>  #define RTE_CRYPTODEV_PMD_MAX_NB_SESS_ARG		("max_nb_sessions")
>>  #define RTE_CRYPTODEV_PMD_SOCKET_ID_ARG			("socket_id")
>> -
>> +#define RTE_CRYPTODEV_PMD_MAX_NB_ASYM_QP_ARG		("max_nb_asym_qp")
>> +#define RTE_CRYPTODEV_PMD_MAX_NB_SYM_QP_ARG		("max_nb_sym_qp")
>>
>>  static const char * const cryptodev_pmd_valid_params[] = {
>>  	RTE_CRYPTODEV_PMD_NAME_ARG,
>>  	RTE_CRYPTODEV_PMD_MAX_NB_QP_ARG,
>>  	RTE_CRYPTODEV_PMD_MAX_NB_SESS_ARG,
>> -	RTE_CRYPTODEV_PMD_SOCKET_ID_ARG
>> +	RTE_CRYPTODEV_PMD_SOCKET_ID_ARG,
>> +	RTE_CRYPTODEV_PMD_MAX_NB_ASYM_QP_ARG,
>> +	RTE_CRYPTODEV_PMD_MAX_NB_SYM_QP_ARG
>>  };
>>
>>  /**
>> @@ -84,6 +91,10 @@ struct rte_cryptodev_pmd_init_params {
>>  	int socket_id;
>>  	unsigned int max_nb_queue_pairs;
>>  	unsigned int max_nb_sessions;
>> +	unsigned int max_nb_asym_qp;
>> +	/**< maximum number of qp to be used for asymmetric ops */
>> +	unsigned int max_nb_sym_qp;
>> +	/**< maximum number of qp to be used for symmetric ops */
>>  };
>>
>>  /** Global structure used for maintaining state of allocated crypto devices */
>> @@ -275,7 +286,29 @@ typedef int (*cryptodev_queue_pair_release_t)(struct rte_cryptodev *dev,
>>  typedef uint32_t (*cryptodev_queue_pair_count_t)(struct rte_cryptodev *dev);
>>
>>  /**
>> - * Create a session mempool to allocate sessions from
>> + * Get number of available symmetric queue pairs of a device.
>> + *
>> + * @param	dev	Crypto device pointer
>> + *
>> + * @return
>> + * - Returns number of symmetric queue pairs
>> + */
>> +typedef uint32_t (*cryptodev_sym_queue_pair_count_t)(
>> +			struct rte_cryptodev *dev);
>> +
>> +/**
>> + * Get number of available asymmetric queue pairs of a device.
>> + *
>> + * @param	dev	Crypto device pointer
>> + *
>> + * @return
>> + * - Returns number of symmetric queue pairs
>> + */
>> +typedef uint32_t (*cryptodev_asym_queue_pair_count_t)(
>> +			struct rte_cryptodev *dev);
>> +
>[Fiona] Is something calling either of above fns? If not better to remove the asym one.
>The sym one should be deprecated and removed in a separate patch.
>
>> +/**
>> + * Create a symmetric session mempool to allocate sessions from
>>   *
>>   * @param	dev		Crypto device pointer
>>   * @param	nb_objs		number of sessions objects in mempool
>> @@ -290,6 +323,21 @@ typedef int (*cryptodev_sym_create_session_pool_t)(
>>  		struct rte_cryptodev *dev, unsigned nb_objs,
>>  		unsigned obj_cache_size, int socket_id);
>>
>> +/**
>> + * Create a asymmetric session mempool to allocate sessions from
>> + *
>> + * @param	dev		Crypto device pointer
>> + * @param	nb_objs		Number of asymmetric sessions objects in mempool
>> + * @param	obj_cache	l-core object cache size, see *rte_ring_create*
>> + * @param	socket_id	Socket Id to allocate  mempool on.
>> + *
>> + * @return
>> + * - On success returns a pointer to a rte_mempool
>> + * - On failure returns a NULL pointer
>> + */
>> +typedef int (*cryptodev_asym_create_session_pool_t)(
>> +		struct rte_cryptodev *dev, unsigned nb_objs,
>> +		unsigned obj_cache_size, int socket_id);
>>
>[Fiona] session pools are not created now per device so this is never called for sym and
>should be deprecated. So no need to add for asym
>
>>  /**
>>   * Get the size of a cryptodev session
>> @@ -302,6 +350,17 @@ typedef int (*cryptodev_sym_create_session_pool_t)(
>>   */
>>  typedef unsigned (*cryptodev_sym_get_session_private_size_t)(
>>  		struct rte_cryptodev *dev);
>> +/**
>> + * Get the size of a asymmetric cryptodev session
>> + *
>> + * @param	dev		Crypto device pointer
>> + *
>> + * @return
>> + *  - On success returns the size of the session structure for device
>> + *  - On failure returns 0
>> + */
>> +typedef unsigned (*cryptodev_asym_get_session_private_size_t)(
>> +		struct rte_cryptodev *dev);
>>
>>  /**
>>   * Configure a Crypto session on a device.
>> @@ -321,7 +380,24 @@ typedef int (*cryptodev_sym_configure_session_t)(struct rte_cryptodev *dev,
>>  		struct rte_crypto_sym_xform *xform,
>>  		struct rte_cryptodev_sym_session *session,
>>  		struct rte_mempool *mp);
>> -
>> +/**
>> + * Configure a Crypto asymmetric session on a device.
>> + *
>> + * @param	dev		Crypto device pointer
>> + * @param	xform		Single or chain of crypto xforms
>> + * @param	priv_sess	Pointer to cryptodev's private session structure
>> + * @param	mp		Mempool where the private session is allocated
>> + *
>> + * @return
>> + *  - Returns 0 if private session structure have been created successfully.
>> + *  - Returns -EINVAL if input parameters are invalid.
>> + *  - Returns -ENOTSUP if crypto device does not support the crypto transform.
>> + *  - Returns -ENOMEM if the private session could not be allocated.
>> + */
>> +typedef int (*cryptodev_asym_configure_session_t)(struct rte_cryptodev *dev,
>> +		struct rte_crypto_asym_xform *xform,
>> +		struct rte_cryptodev_asym_session *session,
>> +		struct rte_mempool *mp);
>>  /**
>>   * Free driver private session data.
>>   *
>> @@ -332,6 +408,15 @@ typedef void (*cryptodev_sym_free_session_t)(struct rte_cryptodev *dev,
>>  		struct rte_cryptodev_sym_session *sess);
>>
>>  /**
>> + * Free asymmetric session private data.
>> + *
>> + * @param	dev		Crypto device pointer
>> + * @param	sess		Cryptodev session structure
>> + */
>> +typedef void (*cryptodev_asym_free_session_t)(struct rte_cryptodev *dev,
>> +		struct rte_cryptodev_asym_session *sess);
>> +
>> +/**
>>   * Optional API for drivers to attach sessions with queue pair.
>>   * @param	dev		Crypto device pointer
>>   * @param	qp_id		queue pair id for attaching session
>> @@ -343,6 +428,18 @@ typedef int (*cryptodev_sym_queue_pair_attach_session_t)(
>>  		  struct rte_cryptodev *dev,
>>  		  uint16_t qp_id,
>>  		  void *session_private);
>> +/**
>> + * Optional API for drivers to attach asymmetric session with queue pair.
>> + * @param	dev		Crypto device pointer
>> + * @param	qp_id		Queue pair id for attaching session
>> + * @param	priv_sess       Pointer to cryptodev's private session structure
>> + * @return
>> + *  - Return 0 on success
>> + */
>> +typedef int (*cryptodev_asym_queue_pair_attach_session_t)(
>> +		  struct rte_cryptodev *dev,
>> +		  uint16_t qp_id,
>> +		  void *session_private);
>>
>>  /**
>>   * Optional API for drivers to detach sessions from queue pair.
>> @@ -357,6 +454,19 @@ typedef int (*cryptodev_sym_queue_pair_detach_session_t)(
>>  		  uint16_t qp_id,
>>  		  void *session_private);
>>
>> +/**
>> + * Optional API for drivers to detach asymmetric session from queue pair.
>> + * @param	dev		Crypto device pointer
>> + * @param	qp_id		queue pair id for detaching session
>> + * @param	priv_sess       Pointer to cryptodev's private session structure
>> + * @return
>> + *  - Return 0 on success
>> + */
>> +typedef int (*cryptodev_asym_queue_pair_detach_session_t)(
>> +		  struct rte_cryptodev *dev,
>> +		  uint16_t qp_id,
>> +		  void *session_private);
>> +
>>  /** Crypto device operations function pointer table */
>>  struct rte_cryptodev_ops {
>>  	cryptodev_configure_t dev_configure;	/**< Configure device. */
>> @@ -380,17 +490,32 @@ struct rte_cryptodev_ops {
>>  	cryptodev_queue_pair_stop_t queue_pair_stop;
>>  	/**< Stop a queue pair. */
>>  	cryptodev_queue_pair_count_t queue_pair_count;
>> -	/**< Get count of the queue pairs. */
>> -
>> +	/**< Get total count of the queue pairs(symmetric+asymmetric). */
>> +	cryptodev_sym_queue_pair_count_t sym_queue_pair_count;
>> +	/**< Get count of the symmetric queue pairs. */
>> +	cryptodev_asym_queue_pair_count_t asym_queue_pair_count;
>> +	/**< Get count of the asymmetric queue pairs. */
>>  	cryptodev_sym_get_session_private_size_t session_get_size;
>> -	/**< Return private session. */
>> +	/**< Return private size for a session */
>> +	cryptodev_sym_get_session_private_size_t sym_session_get_size;
>> +	/**< Return private size for symmetric crypto. */
>> +	cryptodev_sym_get_session_private_size_t asym_session_get_size;
>> +	/**< Return private size for asymmetric crypto. */
>>  	cryptodev_sym_configure_session_t session_configure;
>>  	/**< Configure a Crypto session. */
>[Fiona] This should really be renamed sym_session_configure, same for session_clear,
>qp_attach_session and qp_detach_session
>
>> +	cryptodev_asym_configure_session_t asym_session_configure;
>> +	/**< Configure asymmetric Crypto session. */
>>  	cryptodev_sym_free_session_t session_clear;
>>  	/**< Clear a Crypto sessions private data. */
>> +	cryptodev_asym_free_session_t asym_session_clear;
>> +	/**< Clear a Crypto sessions private data. */
>>  	cryptodev_sym_queue_pair_attach_session_t qp_attach_session;
>>  	/**< Attach session to queue pair. */
>> -	cryptodev_sym_queue_pair_detach_session_t qp_detach_session;
>> +	cryptodev_asym_queue_pair_attach_session_t asym_qp_attach_session;
>> +	/**< Attach asymmetric session to queue pair. */
>> +	cryptodev_sym_queue_pair_attach_session_t qp_detach_session;
>> +	/**< Detach session from queue pair. */
>[Fiona] typo (based on a typo I think was fixed in a recent patch)
>> +	cryptodev_asym_queue_pair_attach_session_t asym_qp_detach_session;
>>  	/**< Detach session from queue pair. */
>>  };
>>
>> @@ -535,6 +660,19 @@ uint8_t rte_cryptodev_allocate_driver(struct cryptodev_driver *crypto_drv,
>>  	sess->sess_private_data[driver_id] = private_data;
>>  }
>>
>> +static inline void *
>> +get_asym_session_private_data(const struct rte_cryptodev_asym_session *sess,
>> +		uint8_t driver_id) {
>> +	return sess->sess_private_data[driver_id];
>> +}
>> +
>> +static inline void
>> +set_asym_session_private_data(struct rte_cryptodev_asym_session *sess,
>> +		uint8_t driver_id, void *private_data)
>> +{
>> +	sess->sess_private_data[driver_id] = private_data;
>> +}
>> +
>>  #ifdef __cplusplus
>>  }
>>  #endif
>> diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map
>> b/lib/librte_cryptodev/rte_cryptodev_version.map
>> index eb47308..323294a 100644
>> --- a/lib/librte_cryptodev/rte_cryptodev_version.map
>> +++ b/lib/librte_cryptodev/rte_cryptodev_version.map
>> @@ -85,3 +85,24 @@ DPDK_17.11 {
>>  	rte_cryptodev_pmd_parse_input_args;
>>
>>  } DPDK_17.08;
>> +
>> +EXPERIMENTAL {
>> +	global:
>> +
>[Fiona] the implementation of all these APIs also needs the _experimental tag.
>
>> +	rte_cryptodev_asym_capability_get;
>> +	rte_cryptodev_asym_capability_modlen;
>> +	rte_cryptodev_asym_queue_pair_count;
>> +	rte_cryptodev_asym_session_create;
>> +	rte_cryptodev_asym_session_clear;
>> +	rte_cryptodev_asym_session_free;
>> +	rte_cryptodev_asym_session_init;
>> +	rte_cryptodev_get_asym_session_private_size;
>> +	rte_cryptodev_get_sym_session_private_size;
>> +	rte_cryptodev_get_xform_algo_enum;
>> +	rte_cryptodev_queue_pair_attach_asym_session;
>> +	rte_cryptodev_queue_pair_detach_asym_session;
>> +	rte_cryptodev_sym_queue_pair_count;
>> +	rte_crypto_asym_xform_strings;
>> +	rte_crypto_asym_operation_strings;
>> +
>> +};
>> --
>> 1.9.1



More information about the dev mailing list