diff --git a/lib/librte_cryptodev/rte_crypto_sym.h b/lib/librte_cryptodev/rte_crypto_sym.h
index d8d9e9514..45f3840bb 100644
--- a/lib/librte_cryptodev/rte_crypto_sym.h
+++ b/lib/librte_cryptodev/rte_crypto_sym.h
@@ -166,6 +166,10 @@ struct rte_crypto_cipher_xform {
 	 *  - Both keys must have the same size.
 	 **/
 
+	/**
+	 * CPU-CRYPTO specific data, used only by rte_crypto_cpu_sym_session
+	 * initialisation pass, otherwise ignored.
+	 */
 	struct {
 		/**
 		 * offset for cipher to start within user provided data buffer.
@@ -415,6 +419,10 @@ struct rte_crypto_aead_xform {
 		uint16_t length;	/**< key length in bytes */
 	} __attribute__((__packed__)) key;
 
+	/**
+	 * CPU-CRYPTO specific data, used only by rte_crypto_cpu_sym_session
+	 * initialisation pass, otherwise ignored.
+	 */
 	struct {
 		/**
 		 * offset for cipher to start within user provided data buffer.
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 89aa2ed3e..8109665c2 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -1616,6 +1616,52 @@ rte_cryptodev_sym_session_get_user_data(
 	return (void *)(sess->sess_data + sess->nb_drivers);
 }
 
+__rte_experimental
+int
+rte_crypto_cpu_sym_session_size(uint8_t dev_id,
+	const struct rte_crypto_sym_xform *xforms)
+{
+	struct rte_cryptodev *dev;
+
+	dev = rte_cryptodev_pmd_get_dev(dev_id);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->cpu_sym_session_size, -ENOTSUP);
+
+	return dev->dev_ops->cpu_sym_session_size(dev, xforms);
+}
+
+__rte_experimental
+int
+rte_crypto_cpu_sym_session_init(uint8_t dev_id,
+	struct rte_crypto_cpu_sym_session *sess,
+	const struct rte_crypto_sym_xform *xforms)
+{
+	struct rte_cryptodev *dev;
+
+	dev = rte_cryptodev_pmd_get_dev(dev_id);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->cpu_sym_session_init, -ENOTSUP);
+
+	return dev->dev_ops->cpu_sym_session_init(dev, sess, xforms);
+}
+
+__rte_experimental
+void
+rte_crypto_cpu_sym_session_clear(struct rte_crypto_cpu_sym_session *sess)
+{
+	if (sess != NULL && sess->ops.clear != NULL)
+		return sess->ops.clear(sess);
+}
+
+__rte_experimental
+int
+rte_crypto_cpu_sym_session_process(struct rte_crypto_cpu_sym_session *sess,
+	struct rte_crypto_sym_vec *vec, int32_t status[], uint32_t num)
+{
+	if (sess == NULL || sess->ops.process == NULL)
+		return -EINVAL;
+
+	return sess->ops.process(sess, vec, status, num);
+}
+
 /** Initialise rte_crypto_op mempool element */
 static void
 rte_crypto_op_init(struct rte_mempool *mempool,
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index c6ffa3b35..3333bbe09 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -450,6 +450,8 @@ rte_cryptodev_asym_get_xform_enum(enum rte_crypto_asym_xform_type *xform_enum,
 /**< Support encrypted-digest operations where digest is appended to data */
 #define RTE_CRYPTODEV_FF_ASYM_SESSIONLESS		(1ULL << 20)
 /**< Support asymmetric session-less operations */
+#define RTE_CRYPTODEV_FF_SYM_CPU_CRYPTO		(1ULL << 21)
+/**< Support symmeteric cpu-crypto processing */
 
 
 /**
@@ -1274,6 +1276,75 @@ void *
 rte_cryptodev_sym_session_get_user_data(
 					struct rte_cryptodev_sym_session *sess);
 
+/**
+ * opaque session structure for symmetric CPU-CRYPTO operations.
+ */
+struct rte_crypto_cpu_sym_session;
+
+/**
+ * Calculate required session size in bytes for given set of xforms.
+ * if xforms == NULL, then return the max possible session size,
+ * that would fit session for any supported by the device algorithm.
+ * if CPU-CRYPTO is not supported at all, or requeted in xform
+ * algorithm is not supported, then return -ENOTSUP.
+ * @param   dev_id   ID of device that we want the session to be used on
+ * @param   xforms   Symmetric crypto transform operations to apply on flow
+ *                   processed with this session
+ * @return
+ *  - On success, positive value for required session size in bytes.
+ *  - negative errno value otherwise.
+ */
+__rte_experimental
+int
+rte_crypto_cpu_sym_session_size(uint8_t dev_id,
+		const struct rte_crypto_sym_xform *xforms);
+
+/**
+ * Initialize symmetric CPU-CRYPTO session.
+ * It is caller responsibility to allocate enough space for it.
+ * See rte_crypto_cpu_sym_session_size above.
+ * @param   dev_id   ID of device that we want the session to be used on
+ * @param   sess     Pointer to the raw session buffer
+ * @param   xforms   Symmetric crypto transform operations to apply on flow
+ *                   processed with this session
+ * @return
+ *  - On success, zero.
+ *  - negative errno value otherwise.
+ */
+__rte_experimental
+int
+rte_crypto_cpu_sym_session_init(uint8_t dev_id,
+		struct rte_crypto_cpu_sym_session *sess,
+		const struct rte_crypto_sym_xform *xforms);
+
+/**
+ * De-initialize symmetric CPU-CRYPTO session.
+ * It is caller responsibility to free  the session pointer afterwards.
+ */
+__rte_experimental
+void
+rte_crypto_cpu_sym_session_clear(struct rte_crypto_cpu_sym_session *sess);
+
+/**
+ * Perform actual crypto processing (encrypt/digest or auth/decrypt)
+ * on user provided data.
+ *
+ * @param	sess	cpu-crypto session structure
+ * @param	vec	Array of vectors for input data
+ * @param	status	Array of status values (one per vec)
+ * 			(RTE_CRYPTO_OP_STATUS_* values)
+ * @param	num	Number of elems in vec and status arrays.
+ *
+ * @return
+ *  - Returns negative errno value on error, or non-negative number
+ *    of successfully processed input vectors.
+ *
++*/
+__rte_experimental
+int
+rte_crypto_cpu_sym_session_process(struct rte_crypto_cpu_sym_session *sess,
+	struct rte_crypto_sym_vec *vec, int32_t status[], uint32_t num);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index fba14f2fa..629461315 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -309,6 +309,38 @@ typedef void (*cryptodev_sym_free_session_t)(struct rte_cryptodev *dev,
 typedef void (*cryptodev_asym_free_session_t)(struct rte_cryptodev *dev,
 		struct rte_cryptodev_asym_session *sess);
 
+/**
+ * Calculate required session size in bytes for given set of xforms.
+ * if xforms == NULL, then return the max possible session size,
+ * that would fit session for any supported by the device algorithm.
+ * if CPU-CRYPTO is not supported at all, or requeted in xform
+ * algorithm is not supported, then return -ENOTSUP.
+ * @param	dev	Crypto device pointer
+ * @param	xforms	Symmetric crypto transform operations to apply on flow
+ *                      processed with this session
+ * @return
+ *  - On success, positive value for required session size in bytes.
+ *  - negative errno value otherwise.
+ */
+typedef int (*cryptodev_cpu_sym_session_size_t)(struct rte_cryptodev *dev,
+		const struct rte_crypto_sym_xform *xforms);
+
+/**
+ * Initialize symmetric CPU-CRYPTO session.
+ * It is caller responsibility to allocate enough space for it.
+ * See rte_crypto_cpu_sym_session_size above.
+ * @param	dev	Crypto device pointer
+ * @param	sess	Pointer to the raw session buffer
+ * @param	xforms	Symmetric crypto transform operations to apply on flow
+ *                       processed with this session
+ * @return
+ *  - On success, zero.
+ *  - negative errno value otherwise.
+ */
+typedef int (*cryptodev_cpu_sym_session_init_t)(struct rte_cryptodev *dev,
+		struct rte_crypto_cpu_sym_session *sess,
+		const struct rte_crypto_sym_xform *xforms);
+
 /** Crypto device operations function pointer table */
 struct rte_cryptodev_ops {
 	cryptodev_configure_t dev_configure;	/**< Configure device. */
@@ -342,6 +374,10 @@ struct rte_cryptodev_ops {
 	/**< Clear a Crypto sessions private data. */
 	cryptodev_asym_free_session_t asym_session_clear;
 	/**< Clear a Crypto sessions private data. */
+	cryptodev_cpu_sym_session_size_t cpu_sym_session_size;
+	/**< Calculate required cpu-crypto session size. */
+	cryptodev_cpu_sym_session_init_t cpu_sym_session_init;
+	/**< Initialise cpu-crypto session. */
 };
 
 
@@ -506,6 +542,19 @@ set_asym_session_private_data(struct rte_cryptodev_asym_session *sess,
 	sess->sess_private_data[driver_id] = private_data;
 }
 
+
+struct rte_crypto_cpu_sym_session_ops {
+	void (*clear)(struct rte_crypto_cpu_sym_session *);
+	int (*process)(struct rte_crypto_cpu_sym_session *,
+		struct rte_crypto_sym_vec *, int32_t [], uint32_t);
+};
+
+struct rte_crypto_cpu_sym_session {
+	struct rte_crypto_cpu_sym_session_ops ops;
+	/** session private data starts here. */
+	void *sess_data[0] __rte_cache_min_aligned;
+};
+
 #ifdef __cplusplus
 }
 #endif
