#include <rte_common.h>
#include "rte_crypto_sym.h"
+#include "rte_crypto_asym.h"
/** Crypto operation types */
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 */
union {
struct rte_crypto_sym_op sym[0];
/**< Symmetric operation parameters */
+
+ struct rte_crypto_asym_op asym[0];
+ /**< Asymmetric operation parameters */
+
}; /**< operation specific parameters */
};
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;
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;
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
[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)
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)
{
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_sym_session_clear(uint8_t dev_id,
struct rte_cryptodev_sym_session *sess)
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)
{
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_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_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_user_data(
struct rte_cryptodev_sym_session *sess,
struct rte_crypto_op_pool_private *priv;
unsigned elt_size = sizeof(struct rte_crypto_op) +
- sizeof(struct rte_crypto_sym_op) +
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);
*/
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)
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
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.
*
struct rte_crypto_sym_xform *xforms,
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
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);
+
/**
* Get the size of the header session, for all registered drivers.
*
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.
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);
+
/**
* Provide driver identifier.
*
*/
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.
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.
*
*/
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);
/** Crypto device operations function pointer table */
struct rte_cryptodev_ops {
cryptodev_sym_get_session_private_size_t sym_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 sym_session_configure;
/**< Configure a Crypto session. */
+ cryptodev_asym_configure_session_t asym_session_configure;
+ /**< Configure asymmetric Crypto session. */
cryptodev_sym_free_session_t sym_session_clear;
/**< Clear a Crypto sessions private data. */
+ cryptodev_asym_free_session_t asym_session_clear;
+ /**< Clear a Crypto sessions private data. */
};
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
EXPERIMENTAL {
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_init;
rte_cryptodev_sym_session_get_user_data;
rte_cryptodev_sym_session_set_user_data;
};