@@ -23,6 +23,7 @@ extern "C" {
#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 */
@@ -114,6 +117,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 */
};
@@ -134,6 +141,9 @@ __rte_crypto_op_reset(struct rte_crypto_op *op, enum rte_crypto_op_type type)
case RTE_CRYPTO_OP_TYPE_SYMMETRIC:
__rte_crypto_sym_op_reset(op->sym);
break;
+ case RTE_CRYPTO_OP_TYPE_ASYMMETRIC:
+ memset(op->asym, 0, sizeof(struct rte_crypto_asym_op));
+ break;
case RTE_CRYPTO_OP_TYPE_UNDEFINED:
default:
break;
@@ -300,9 +310,14 @@ __rte_crypto_op_get_priv_data(struct rte_crypto_op *op, uint32_t size)
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;
@@ -405,6 +420,24 @@ rte_crypto_op_attach_sym_session(struct rte_crypto_op *op,
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;
+ op->asym->session = sess;
+ return 0;
+}
+
#ifdef __cplusplus
}
#endif
@@ -166,6 +166,31 @@ rte_crypto_aead_operation_strings[] = {
[RTE_CRYPTO_AEAD_OP_DECRYPT] = "decrypt"
};
+/**
+ * Asymmetric crypto transform operation strings identifiers.
+ */
+const char *rte_crypto_asym_xform_strings[] = {
+ [RTE_CRYPTO_ASYM_XFORM_NONE] = "none",
+ [RTE_CRYPTO_ASYM_XFORM_RSA] = "rsa",
+ [RTE_CRYPTO_ASYM_XFORM_MODEX] = "modexp",
+ [RTE_CRYPTO_ASYM_XFORM_MODINV] = "modinv",
+ [RTE_CRYPTO_ASYM_XFORM_DH] = "dh",
+ [RTE_CRYPTO_ASYM_XFORM_DSA] = "dsa",
+};
+
+/**
+ * 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_PRIVATE_KEY_GENERATE] = "priv_key_generate",
+ [RTE_CRYPTO_ASYM_OP_PUBLIC_KEY_GENERATE] = "pub_key_generate",
+ [RTE_CRYPTO_ASYM_OP_SHARED_SECRET_COMPUTE] = "sharedsecret_compute",
+};
+
int
rte_cryptodev_get_cipher_algo_enum(enum rte_crypto_cipher_algorithm *algo_enum,
const char *algo_string)
@@ -1111,6 +1136,41 @@ rte_cryptodev_sym_session_init(uint8_t dev_id,
return 0;
}
+int __rte_experimental
+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;
+
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->asym_session_configure,
+ -ENOTSUP);
+
+ 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)
{
@@ -1130,6 +1190,25 @@ rte_cryptodev_sym_session_create(struct rte_mempool *mp)
return sess;
}
+struct rte_cryptodev_asym_session * __rte_experimental
+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.
+ * Include the flag indicating presence of private data
+ */
+ memset(sess, 0, (sizeof(void *) * nb_drivers) + sizeof(uint8_t));
+
+ return sess;
+}
+
int
rte_cryptodev_queue_pair_attach_sym_session(uint8_t dev_id, uint16_t qp_id,
struct rte_cryptodev_sym_session *sess)
@@ -1200,6 +1279,24 @@ rte_cryptodev_sym_session_clear(uint8_t dev_id,
return 0;
}
+int __rte_experimental
+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;
+
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->asym_session_clear, -ENOTSUP);
+
+ dev->dev_ops->asym_session_clear(dev, sess);
+
+ return 0;
+}
+
int
rte_cryptodev_sym_session_free(struct rte_cryptodev_sym_session *sess)
{
@@ -1224,6 +1321,31 @@ rte_cryptodev_sym_session_free(struct rte_cryptodev_sym_session *sess)
return 0;
}
+int __rte_experimental
+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)
{
@@ -1241,6 +1363,17 @@ rte_cryptodev_sym_get_header_session_size(void)
return ((sizeof(void *) * nb_drivers) + sizeof(uint8_t));
}
+unsigned int __rte_experimental
+rte_cryptodev_asym_get_header_session_size(void)
+{
+ /*
+ * Header contains pointers to the private data
+ * of all registered drivers, and a flag which
+ * indicates presence of private data
+ */
+ return ((sizeof(void *) * nb_drivers) + sizeof(uint8_t));
+}
+
unsigned int
rte_cryptodev_get_private_session_size(uint8_t dev_id)
{
@@ -1276,6 +1409,29 @@ rte_cryptodev_sym_get_private_session_size(uint8_t dev_id)
}
+unsigned int __rte_experimental
+rte_cryptodev_asym_get_private_session_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;
+
+}
+
int __rte_experimental
rte_cryptodev_sym_session_set_private_data(
struct rte_cryptodev_sym_session *sess,
@@ -1308,6 +1464,39 @@ rte_cryptodev_sym_session_get_private_data(
return (uint8_t *)sess + off_set;
}
+
+int __rte_experimental
+rte_cryptodev_asym_session_set_private_data(
+ struct rte_cryptodev_asym_session *sess,
+ void *data,
+ uint16_t size)
+{
+ uint16_t off_set = sizeof(void *) * nb_drivers;
+ uint8_t *private_data_present = (uint8_t *)sess + off_set;
+
+ if (sess == NULL)
+ return -EINVAL;
+
+ *private_data_present = 1;
+ off_set += sizeof(uint8_t);
+ rte_memcpy((uint8_t *)sess + off_set, data, size);
+ return 0;
+}
+
+void * __rte_experimental
+rte_cryptodev_asym_session_get_app_private_data(
+ struct rte_cryptodev_asym_session *sess)
+{
+ uint16_t off_set = sizeof(void *) * nb_drivers;
+ uint8_t *private_data_present = (uint8_t *)sess + off_set;
+
+ if (sess == NULL || !*private_data_present)
+ return NULL;
+
+ off_set += sizeof(uint8_t);
+ return (uint8_t *)sess + off_set;
+}
+
/** Initialise rte_crypto_op mempool element */
static void
rte_crypto_op_init(struct rte_mempool *mempool,
@@ -1335,8 +1524,16 @@ rte_crypto_op_pool_create(const char *name, enum rte_crypto_op_type type,
struct rte_crypto_op_pool_private *priv;
unsigned elt_size = sizeof(struct rte_crypto_op) +
- sizeof(struct rte_crypto_sym_op) +
- priv_size;
+ priv_size;
+
+ if (type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
+ elt_size += sizeof(struct rte_crypto_sym_op);
+ } else if (type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
+ elt_size += sizeof(struct rte_crypto_asym_op);
+ } else {
+ CDEV_LOG_ERR("Invalid op_type\n");
+ return NULL;
+ }
/* lookup mempool in case already allocated */
struct rte_mempool *mp = rte_mempool_lookup(name);
@@ -867,9 +867,14 @@ rte_cryptodev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
*/
struct rte_cryptodev_sym_session {
__extension__ void *sess_private_data[0];
- /**< Private session material */
+ /**< Private symmetric 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)
@@ -884,6 +889,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_experimental
+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.
@@ -899,6 +916,21 @@ int
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_experimental
+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
@@ -920,6 +952,27 @@ rte_cryptodev_sym_session_init(uint8_t dev_id,
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_experimental
+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. It is the application's responsibility
* to ensure that private session data is not cleared while there are
@@ -937,6 +990,20 @@ rte_cryptodev_sym_session_clear(uint8_t dev_id,
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_experimental
+rte_cryptodev_asym_session_clear(uint8_t dev_id,
+ struct rte_cryptodev_asym_session *sess);
+
+/**
* @deprecated
* Get the size of the header session, for all registered drivers.
*
@@ -971,6 +1038,15 @@ unsigned int
rte_cryptodev_sym_get_header_session_size(void);
/**
+ * Get the size of the asymmetric session header, for all registered drivers.
+ *
+ * @return
+ * Size of the asymmetric header session.
+ */
+unsigned int __rte_experimental
+rte_cryptodev_asym_get_header_session_size(void);
+
+/**
* Get the size of the private symmetric session data
* for a device.
*
@@ -985,6 +1061,19 @@ unsigned int
rte_cryptodev_sym_get_private_session_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_experimental
+rte_cryptodev_asym_get_private_session_size(uint8_t dev_id);
+
+/**
* @deprecated
* Attach queue pair with sym session.
*
@@ -1072,6 +1161,39 @@ void * __rte_experimental
rte_cryptodev_sym_session_get_private_data(
struct rte_cryptodev_sym_session *sess);
+/**
+ * Set private data for a session.
+ *
+ * @param sess Session pointer allocated by
+ * *rte_cryptodev_asym_session_create*.
+ * @param data Pointer to the private data.
+ * @param size Size of the private data.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+int __rte_experimental
+rte_cryptodev_asym_session_set_private_data(
+ struct rte_cryptodev_asym_session *sess,
+ void *data,
+ uint16_t size);
+
+/**
+ * Get private data of a session.
+ *
+ * @param sess Session pointer allocated by
+ * *rte_cryptodev_asym_session_create*.
+ *
+ * @return
+ * - On success return pointer to private data.
+ * - On failure returns NULL.
+ */
+void * __rte_experimental
+rte_cryptodev_asym_session_get_app_private_data(
+ struct rte_cryptodev_asym_session *sess);
+
+
#ifdef __cplusplus
}
#endif
@@ -275,6 +275,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 int (*cryptodev_asym_get_session_private_size_t)(
+ struct rte_cryptodev *dev);
/**
* Configure a Crypto session on a device.
@@ -294,7 +305,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.
*
@@ -305,6 +333,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
@@ -357,10 +394,16 @@ struct rte_cryptodev_ops {
cryptodev_sym_get_session_private_size_t session_get_size;
/**< Return private session. */
+ cryptodev_asym_get_session_private_size_t asym_session_get_size;
+ /**< Return asym session private size. */
cryptodev_sym_configure_session_t session_configure;
/**< Configure a Crypto 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;
@@ -508,6 +551,19 @@ set_session_private_data(struct rte_cryptodev_sym_session *sess,
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
@@ -95,8 +95,16 @@ DPDK_18.05 {
} DPDK_17.11;
EXPERIMENTAL {
- global:
+ global:
+ rte_cryptodev_asym_get_header_session_size;
+ rte_cryptodev_asym_get_private_session_size;
+ rte_cryptodev_asym_session_clear;
+ rte_cryptodev_asym_session_create;
+ rte_cryptodev_asym_session_free;
+ rte_cryptodev_asym_session_get_app_private_data;
+ rte_cryptodev_asym_session_init;
+ rte_cryptodev_asym_session_set_private_data;
rte_cryptodev_sym_session_get_private_data;
rte_cryptodev_sym_session_set_private_data;
};