[dpdk-dev,RFC,1/4] rte_security: API definitions

Message ID 20170815063505.22032-2-akhil.goyal@nxp.com (mailing list archive)
State Superseded, archived
Headers

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/Intel-compilation success Compilation OK

Commit Message

Akhil Goyal Aug. 15, 2017, 6:35 a.m. UTC
  Detailed description is added in the coverletter

Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
---
 lib/librte_cryptodev/rte_security.c | 171 +++++++++++++++
 lib/librte_cryptodev/rte_security.h | 409 ++++++++++++++++++++++++++++++++++++
 2 files changed, 580 insertions(+)
 create mode 100644 lib/librte_cryptodev/rte_security.c
 create mode 100644 lib/librte_cryptodev/rte_security.h
  

Comments

Radu Nicolau Aug. 15, 2017, 11:04 a.m. UTC | #1
On 8/15/2017 7:35 AM, Akhil Goyal wrote:
> Detailed description is added in the coverletter
>
> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
> ---
>   lib/librte_cryptodev/rte_security.c | 171 +++++++++++++++
>   lib/librte_cryptodev/rte_security.h | 409 ++++++++++++++++++++++++++++++++++++
>   2 files changed, 580 insertions(+)
>   create mode 100644 lib/librte_cryptodev/rte_security.c
>   create mode 100644 lib/librte_cryptodev/rte_security.h
>
> diff --git a/lib/librte_cryptodev/rte_security.c b/lib/librte_cryptodev/rte_security.c
> new file mode 100644
> index 0000000..7c73c93
> --- /dev/null
> +++ b/lib/librte_cryptodev/rte_security.c
> @@ -0,0 +1,171 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright 2017 NXP.
> + *
> + *   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 NXP 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.
> + */
> +
> +#include <rte_log.h>
> +#include <rte_debug.h>
> +#include <rte_dev.h>
> +#include <rte_memory.h>
> +#include <rte_memcpy.h>
> +#include <rte_launch.h>
> +#include <rte_common.h>
> +#include <rte_mempool.h>
> +#include <rte_malloc.h>
> +#include <rte_errno.h>
> +
> +#include "rte_crypto.h"
> +#include "rte_cryptodev_pmd.h"
> +#include "rte_security.h"
> +#include "rte_ethdev.h"
> +#include "rte_cryptodev.h"
> +
> +
> +struct rte_security_session *
> +rte_security_session_create(struct rte_mempool *mp)
> +{
> +	struct rte_security_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 *) *
> +		RTE_MAX(rte_eth_dev_count(), rte_cryptodev_count())));
> +
> +	return sess;
> +}
> +
> +int
> +rte_security_session_init(uint16_t dev_id,
> +			  struct rte_security_session *sess,
> +			  struct rte_security_sess_conf *conf,
> +			  struct rte_mempool *mp)
> +{
> +	struct rte_cryptodev *cdev = NULL;
> +	struct rte_eth_dev *dev = NULL;
> +	uint8_t index;
> +	int ret;
> +
> +	if (sess == NULL || conf == NULL)
> +		return -EINVAL;
> +
> +	switch (conf->action_type) {
> +	case RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD:
> +		if (!rte_cryptodev_pmd_is_valid_dev(dev_id))
> +			return -EINVAL;
> +		cdev = rte_cryptodev_pmd_get_dev(dev_id);
> +		index = cdev->driver_id;
> +		if (sess->sess_private_data[index] == NULL) {
> +			ret = cdev->sec_ops->session_configure(cdev, conf, sess, mp);
> +			if (ret < 0) {
> +				CDEV_LOG_ERR(
> +					"cdev_id %d failed to configure session details",
> +					dev_id);
> +				return ret;
> +			}
> +		}
> +		break;
> +	case RTE_SECURITY_SESS_ETH_INLINE_CRYPTO:
> +	case RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD:
> +		dev = &rte_eth_devices[dev_id];
> +		index = dev->data->port_id;
> +		if (sess->sess_private_data[index] == NULL) {
> +//			ret = dev->sec_ops->session_configure(dev, conf, sess, mp);
> +//			if (ret < 0) {
> +//				CDEV_LOG_ERR(
> +//					"dev_id %d failed to configure session details",
> +//					dev_id);
> +//				return ret;
> +//			}
The commented lines above suggests that also eth devices will have a 
sec_ops field, (which makes sense). Is this correct?
Also, if the above is correct, session_configure and session_clear 
should accept both crypto and eth devices as first parameter.
> +		}
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +int
> +rte_security_session_free(struct rte_security_session *sess)
> +{
> +	uint8_t i, nb_drivers = RTE_MAX(rte_eth_dev_count(),
> +					rte_cryptodev_count());
> +	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_sec_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;
> +}
> +
> +int
> +rte_security_session_clear(uint8_t dev_id,
> +		enum rte_security_session_action_type action_type,
> +		struct rte_security_session *sess)
> +{
> +	struct rte_cryptodev *cdev = NULL;
> +	struct rte_eth_dev *dev = NULL;
> +	switch (action_type) {
> +	case RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD:
> +		cdev =  rte_cryptodev_pmd_get_dev(dev_id);
> +		if (cdev == NULL || sess == NULL)
> +			return -EINVAL;
> +		cdev->sec_ops->session_clear(cdev, sess);
> +		break;
> +	case RTE_SECURITY_SESS_ETH_INLINE_CRYPTO:
> +	case RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD:
> +		dev = &rte_eth_devices[dev_id];
> +		if (dev == NULL || sess == NULL)
> +			return -EINVAL;
> +//		dev->dev_ops->session_clear(dev, sess);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> diff --git a/lib/librte_cryptodev/rte_security.h b/lib/librte_cryptodev/rte_security.h
> new file mode 100644
> index 0000000..9747d5e
> --- /dev/null
> +++ b/lib/librte_cryptodev/rte_security.h
> @@ -0,0 +1,409 @@
> +#ifndef _RTE_SECURITY_H_
> +#define _RTE_SECURITY_H_
> +
> +/**
> + * @file rte_security.h
> + *
> + * RTE Security Common Definitions
> + *
> + */
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#include <netinet/in.h>
> +#include <netinet/ip.h>
> +#include <netinet/ip6.h>
> +
> +#include <rte_mbuf.h>
> +#include <rte_memory.h>
> +#include <rte_mempool.h>
> +#include <rte_common.h>
> +#include <rte_crypto.h>
> +
> +/** IPSec protocol mode */
> +enum rte_security_conf_ipsec_sa_mode {
> +	RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
> +	/**< IPSec Transport mode */
> +	RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
> +	/**< IPSec Tunnel mode */
> +};
> +
> +/** IPSec Protocol */
> +enum rte_security_conf_ipsec_sa_protocol {
> +	RTE_SECURITY_IPSEC_SA_PROTO_AH,
> +	/**< AH protocol */
> +	RTE_SECURITY_IPSEC_SA_PROTO_ESP,
> +	/**< ESP protocol */
> +};
> +
> +/** IPSEC tunnel type */
> +enum rte_security_ipsec_tunnel_type {
> +	RTE_SECURITY_IPSEC_TUNNEL_IPV4 = 0,
> +	/**< Outer header is IPv4 */
> +	RTE_SECURITY_IPSEC_TUNNEL_IPV6,
> +	/**< Outer header is IPv6 */
> +};
> +
> +/**
> + * IPSEC tunnel parameters
> + *
> + * These parameters are used to build outbound tunnel headers.
> + */
> +struct rte_security_ipsec_tunnel_param {
> +	enum rte_security_ipsec_tunnel_type type;
> +	/**< Tunnel type: IPv4 or IPv6 */
> +
> +	union {
> +		struct {
> +			struct in_addr src_ip;
> +			/**< IPv4 source address */
> +			struct in_addr dst_ip;
> +			/**< IPv4 destination address */
> +			uint8_t dscp;
> +			/**< IPv4 Differentiated Services Code Point */
> +			uint8_t df;
> +			/**< IPv4 Don't Fragment bit */
> +			uint8_t ttl;
> +			/**< IPv4 Time To Live */
> +		} ipv4; /**< IPv4 header parameters */
> +
> +		struct {
> +			struct in6_addr *src_addr;
> +			/**< IPv6 source address */
> +			struct in6_addr *dst_addr;
> +			/**< IPv6 destination address */
> +			uint8_t dscp;
> +			/**< IPv6 Differentiated Services Code Point */
> +			uint32_t flabel;
> +			/**< IPv6 flow label */
> +			uint8_t hlimit;
> +			/**< IPv6 hop limit */
> +		} ipv6; /**< IPv6 header parameters */
> +	}; /**< Various tunnel parameters */
> +};
> +
> +/**
> + * IPSEC SA option flags
> + */
> +struct rte_security_ipsec_sa_options {
> +	/** Extended Sequence Numbers (ESN)
> +	  *
> +	  * * 1: Use extended (64 bit) sequence numbers
> +	  * * 0: Use normal sequence numbers
> +	  */
> +	uint32_t esn : 1;
> +
> +	/** UDP encapsulation
> +	  *
> +	  * * 1: Do UDP encapsulation/decapsulation so that IPSEC packets can
> +	  *      traverse through NAT boxes.
> +	  * * 0: No UDP encapsulation
> +	  */
> +	uint32_t udp_encap : 1;
> +
> +	/** Copy DSCP bits
> +	  *
> +	  * * 1: Copy IPv4 or IPv6 DSCP bits from inner IP header to
> +	  *      the outer IP header in encapsulation, and vice versa in
> +	  *      decapsulation.
> +	  * * 0: Use values from odp_ipsec_tunnel_param_t in encapsulation and
> +	  *      do not change DSCP field in decapsulation.
> +	  */
> +	uint32_t copy_dscp : 1;
> +
> +	/** Copy IPv6 Flow Label
> +	  *
> +	  * * 1: Copy IPv6 flow label from inner IPv6 header to the
> +	  *      outer IPv6 header.
> +	  * * 0: Use value from odp_ipsec_tunnel_param_t
> +	  */
> +	uint32_t copy_flabel : 1;
> +
> +	/** Copy IPv4 Don't Fragment bit
> +	  *
> +	  * * 1: Copy the DF bit from the inner IPv4 header to the outer
> +	  *      IPv4 header.
> +	  * * 0: Use value from odp_ipsec_tunnel_param_t
> +	  */
> +	uint32_t copy_df : 1;
> +
> +	/** Decrement inner packet Time To Live (TTL) field
> +	  *
> +	  * * 1: In tunnel mode, decrement inner packet IPv4 TTL or
> +	  *      IPv6 Hop Limit after tunnel decapsulation, or before tunnel
> +	  *      encapsulation.
> +	  * * 0: Inner packet is not modified.
> +	  */
> +	uint32_t dec_ttl : 1;
> +
> +};
> +
> +/** IPSec Operations */
> +enum rte_security_ipsec_operation {
> +	RTE_SECURITY_IPSEC_OP_ENCAP,
> +	/**< Encrypt and generate digest */
> +	RTE_SECURITY_IPSEC_OP_DECAP,
> +	/**< Verify digest and decrypt */
> +};
> +
> +/**
> + * IPSec Setup Data.
> + *
> + * This structure contains data relating to IPSec
> + * used to create a session.
> + */
> +struct rte_security_ipsec_xform {
> +	enum rte_security_ipsec_operation op;
> +	/**< IPSec operation - Encap or Decap */
> +	unsigned int spi;
> +	/**< SA security parameter index */
> +	enum rte_crypto_cipher_algorithm cipher_alg;
> +	/**< Cipher Algorithm */
> +	struct {
> +		uint8_t *data;  /**< pointer to key data */
> +		size_t length;   /**< key length in bytes */
> +	} cipher_key;
> +	enum rte_crypto_auth_algorithm auth_alg;
> +	/**< Authentication Algorithm */
> +	struct {
> +		uint8_t *data;  /**< pointer to key data */
> +		size_t length;   /**< key length in bytes */
> +	} auth_key;
> +	uint32_t salt;	/**< salt for this SA */
> +	enum rte_security_conf_ipsec_sa_mode mode;
> +	/**< IPsec SA Mode - transport/tunnel */
> +	enum rte_security_conf_ipsec_sa_protocol proto;
> +	/**< IPsec SA Protocol - AH/ESP */
> +	struct rte_security_ipsec_tunnel_param tunnel;
> +	/**< Tunnel parameters, NULL for transport mode */
> +	struct rte_security_ipsec_sa_options options;
> +	/**< various SA options */
> +};
> +
> +/** IPsec Security Session Configuration */
> +struct rte_security_dtls_xform {
> +	/** To be Filled */
> +};
> +
> +/** IPsec Security Session Configuration */
> +struct rte_security_macsec_xform {
> +	/** To be Filled */
> +};
> +
> +/**< Security Session action type */
> +enum rte_security_session_action_type {
> +	RTE_SECURITY_SESS_NONE,
> +	/**< Non protocol offload. Application need to manage everything */
> +	RTE_SECURITY_SESS_ETH_INLINE_CRYPTO,
> +	/**< Crypto operations are performed by Network interface */
> +	RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD,
> +	/**< Crypto operations with protocol support are performed
> +	 * by Network/ethernet device.
> +	 */
> +	RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD,
> +	/**< Crypto operations with protocol support are performed
> +	 * by Crypto device.
> +	 */
> +};
> +
> +/** Security Session Protocols */
> +enum rte_security_sess_protocol {
> +	RTE_SEC_CONF_DTLS,
> +	/**< DTLS Protocol */
> +	RTE_SEC_CONF_IPSEC,
> +	/**< IPSec Protocol */
> +	RTE_SEC_CONF_MACSEC,
> +	/**< MACSec Protocol */
> +};
> +
> +/**
> + * Security Session Configuration
> + */
> +struct rte_security_sess_conf {
> +	enum rte_security_session_action_type action_type;
> +	/**< Type of action to be performed on the session */
> +	enum rte_security_sess_protocol protocol;
> +	/**< Security protocol to be configured */
> +
> +	union {
> +		struct rte_security_ipsec_xform *ipsec_xform;
> +		struct rte_security_dtls_xform *dtls_xform;
> +		struct rte_security_macsec_xform *macsec_xform;
> +	};
> +	/**< Configuration parameters for security session */
> +};
> +
> +struct rte_security_session {
> +	__extension__ void *sess_private_data[0];
> +	/**< Private session material */
> +};
> +
> +/**
> + * Create Security session header (generic with no private data)
> + *
> + * @param   mempool    Session mempool to allocate session objects from
> + * @return
> + *  - On success, pointer to session
> + *  - On failure, NULL
> + */
> +struct rte_security_session *
> +rte_security_session_create(struct rte_mempool *mempool);
> +
> +/**
> + * Fill out private data for the device, based on its device id and name.
> + *
> + * @param   dev_id   Device id that we want the session to be used on
> + * @param   dev_name Device name for which session is to be used
> + * @param   sess     Session where the private data will be attached to
> + * @param   conf     Security config to apply on flow
> + *                   processed with this session
> + * @param   mempool  Mempool where the private data is allocated.
> + *
> + * @return
> + *  - On success, zero.
> + *  - On failure, a negative value.
> + */
> +int
> +rte_security_session_init(uint16_t dev_id,
> +			  struct rte_security_session *sess,
> +			  struct rte_security_sess_conf *conf,
> +			  struct rte_mempool *mempool);
> +
> +/**
> + * Frees Security 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_security_session_free(struct rte_security_session *sess);
> +
> +/**
> + * Frees private data for the device id, based on its device name,
> + * returning it to its mempool.
> + *
> + * @param   dev_id	ID of device that uses the session.
> + * @param   action_type	Action type for Security operation.
> + * @param   sess	Session containing the reference to the private data
> + *
> + * @return
> + *  - 0 if successful.
> + *  - -EINVAL if device is invalid or session is NULL.
> + */
> +int
> +rte_security_session_clear(uint8_t dev_id,
> +			   enum rte_security_session_action_type action_type,
> +			   struct rte_security_session *sess);
> +
> +/**
> + * Attach a session to a symmetric crypto operation
> + *
> + * @param	sym_op	crypto operation
> + * @param	sess	security session
> + */
> +static inline int
> +__rte_security_attach_session(struct rte_crypto_sym_op *sym_op,
> +			      struct rte_security_session *sess)
> +{
> +	sym_op->sec_session = sess;
> +
> +	return 0;
> +}
> +
> +static inline void *
> +get_sec_session_private_data(const struct rte_security_session *sess,
> +		uint8_t driver_id) {
> +	return sess->sess_private_data[driver_id];
> +}
> +
> +static inline void
> +set_sec_session_private_data(struct rte_security_session *sess,
> +		uint8_t driver_id, void *private_data)
> +{
> +	sess->sess_private_data[driver_id] = private_data;
> +}
> +
> +/**
> + * Attach a session to a crypto operation.
> + * This API is needed only in case of RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD
> + * For other rte_security_session_action_type, ol_flags in rte_mbuf may be
> + * defined to perform security operations.
> + *
> + * @param	op	crypto operation
> + * @param	sess	security session
> + */
> +static inline int
> +rte_security_attach_session(struct rte_crypto_op *op,
> +			    struct rte_security_session *sess)
> +{
> +	if (unlikely(op->type != RTE_CRYPTO_OP_TYPE_SYMMETRIC))
> +		return -1;
> +
> +	op->sess_type = RTE_CRYPTO_OP_WITH_SESSION;
> +
> +	return __rte_security_attach_session(op->sym, sess);
> +}
> +
> +/**
> + * Security Capability
> + */
> +struct rte_security_capabilities {
> +	enum rte_security_sess_protocol protocol;
> +	RTE_STD_C11
> +	union {
> +		struct {
> +			enum rte_crypto_auth_algorithm a_algo;
> +			/**< authentication algorithm */
> +			enum rte_crypto_cipher_algorithm c_algo;
> +			/**< cipher algorithm */
> +			uint16_t block_size;
> +			/**< algorithm block size */
> +			struct rte_crypto_param_range c_key_size;
> +			/**< cipher key size range */
> +			struct rte_crypto_param_range a_key_size;
> +			/**< auth key size range */
> +			struct rte_crypto_param_range digest_size;
> +			/**< digest size range */
> +			struct rte_crypto_param_range iv_size;
> +			/**< Initialisation vector data size range */
> +		} ipsec;
> +		/**< IPSEC transform capabilities */
> +		struct {
> +			/* To be Filled */
> +		} dtls;
> +		/**< DTLS transform capabilities */
> +		struct {
> +			/* To be Filled */
> +		} macsec;
> +		/**< MACSEC transform capabilities */
> +	};
> +};
> +
> +/**
> + *  Provide capabilities available for defined device and algorithm
> + *
> + * @param	dev_id		The identifier of the device.
> + * @param	dev_name	Device name for which capability is needed
> + * @param	protocol	Protocol for which capability is required
> + *
> + * @return
> + *   - Return description of the security capability if exist.
> + *   - Return NULL if the capability not exist.
> + */
> +const struct rte_security_capabilities *
> +rte_security_capability_get(uint8_t dev_id, char *dev_name,
> +		enum rte_security_sess_protocol protocol);
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_SECURITY_H_ */
  

Patch

diff --git a/lib/librte_cryptodev/rte_security.c b/lib/librte_cryptodev/rte_security.c
new file mode 100644
index 0000000..7c73c93
--- /dev/null
+++ b/lib/librte_cryptodev/rte_security.c
@@ -0,0 +1,171 @@ 
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright 2017 NXP.
+ *
+ *   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 NXP 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.
+ */
+
+#include <rte_log.h>
+#include <rte_debug.h>
+#include <rte_dev.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_launch.h>
+#include <rte_common.h>
+#include <rte_mempool.h>
+#include <rte_malloc.h>
+#include <rte_errno.h>
+
+#include "rte_crypto.h"
+#include "rte_cryptodev_pmd.h"
+#include "rte_security.h"
+#include "rte_ethdev.h"
+#include "rte_cryptodev.h"
+
+
+struct rte_security_session *
+rte_security_session_create(struct rte_mempool *mp)
+{
+	struct rte_security_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 *) *
+		RTE_MAX(rte_eth_dev_count(), rte_cryptodev_count())));
+
+	return sess;
+}
+
+int
+rte_security_session_init(uint16_t dev_id,
+			  struct rte_security_session *sess,
+			  struct rte_security_sess_conf *conf,
+			  struct rte_mempool *mp)
+{
+	struct rte_cryptodev *cdev = NULL;
+	struct rte_eth_dev *dev = NULL;
+	uint8_t index;
+	int ret;
+
+	if (sess == NULL || conf == NULL)
+		return -EINVAL;
+
+	switch (conf->action_type) {
+	case RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD:
+		if (!rte_cryptodev_pmd_is_valid_dev(dev_id))
+			return -EINVAL;
+		cdev = rte_cryptodev_pmd_get_dev(dev_id);
+		index = cdev->driver_id;
+		if (sess->sess_private_data[index] == NULL) {
+			ret = cdev->sec_ops->session_configure(cdev, conf, sess, mp);
+			if (ret < 0) {
+				CDEV_LOG_ERR(
+					"cdev_id %d failed to configure session details",
+					dev_id);
+				return ret;
+			}
+		}
+		break;
+	case RTE_SECURITY_SESS_ETH_INLINE_CRYPTO:
+	case RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD:
+		dev = &rte_eth_devices[dev_id];
+		index = dev->data->port_id;
+		if (sess->sess_private_data[index] == NULL) {
+//			ret = dev->sec_ops->session_configure(dev, conf, sess, mp);
+//			if (ret < 0) {
+//				CDEV_LOG_ERR(
+//					"dev_id %d failed to configure session details",
+//					dev_id);
+//				return ret;
+//			}
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int
+rte_security_session_free(struct rte_security_session *sess)
+{
+	uint8_t i, nb_drivers = RTE_MAX(rte_eth_dev_count(),
+					rte_cryptodev_count());
+	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_sec_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;
+}
+
+int
+rte_security_session_clear(uint8_t dev_id,
+		enum rte_security_session_action_type action_type,
+		struct rte_security_session *sess)
+{
+	struct rte_cryptodev *cdev = NULL;
+	struct rte_eth_dev *dev = NULL;
+	switch (action_type) {
+	case RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD:
+		cdev =  rte_cryptodev_pmd_get_dev(dev_id);
+		if (cdev == NULL || sess == NULL)
+			return -EINVAL;
+		cdev->sec_ops->session_clear(cdev, sess);
+		break;
+	case RTE_SECURITY_SESS_ETH_INLINE_CRYPTO:
+	case RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD:
+		dev = &rte_eth_devices[dev_id];
+		if (dev == NULL || sess == NULL)
+			return -EINVAL;
+//		dev->dev_ops->session_clear(dev, sess);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
diff --git a/lib/librte_cryptodev/rte_security.h b/lib/librte_cryptodev/rte_security.h
new file mode 100644
index 0000000..9747d5e
--- /dev/null
+++ b/lib/librte_cryptodev/rte_security.h
@@ -0,0 +1,409 @@ 
+#ifndef _RTE_SECURITY_H_
+#define _RTE_SECURITY_H_
+
+/**
+ * @file rte_security.h
+ *
+ * RTE Security Common Definitions
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+
+#include <rte_mbuf.h>
+#include <rte_memory.h>
+#include <rte_mempool.h>
+#include <rte_common.h>
+#include <rte_crypto.h>
+
+/** IPSec protocol mode */
+enum rte_security_conf_ipsec_sa_mode {
+	RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT,
+	/**< IPSec Transport mode */
+	RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
+	/**< IPSec Tunnel mode */
+};
+
+/** IPSec Protocol */
+enum rte_security_conf_ipsec_sa_protocol {
+	RTE_SECURITY_IPSEC_SA_PROTO_AH,
+	/**< AH protocol */
+	RTE_SECURITY_IPSEC_SA_PROTO_ESP,
+	/**< ESP protocol */
+};
+
+/** IPSEC tunnel type */
+enum rte_security_ipsec_tunnel_type {
+	RTE_SECURITY_IPSEC_TUNNEL_IPV4 = 0,
+	/**< Outer header is IPv4 */
+	RTE_SECURITY_IPSEC_TUNNEL_IPV6,
+	/**< Outer header is IPv6 */
+};
+
+/**
+ * IPSEC tunnel parameters
+ *
+ * These parameters are used to build outbound tunnel headers.
+ */
+struct rte_security_ipsec_tunnel_param {
+	enum rte_security_ipsec_tunnel_type type;
+	/**< Tunnel type: IPv4 or IPv6 */
+
+	union {
+		struct {
+			struct in_addr src_ip;
+			/**< IPv4 source address */
+			struct in_addr dst_ip;
+			/**< IPv4 destination address */
+			uint8_t dscp;
+			/**< IPv4 Differentiated Services Code Point */
+			uint8_t df;
+			/**< IPv4 Don't Fragment bit */
+			uint8_t ttl;
+			/**< IPv4 Time To Live */
+		} ipv4; /**< IPv4 header parameters */
+
+		struct {
+			struct in6_addr *src_addr;
+			/**< IPv6 source address */
+			struct in6_addr *dst_addr;
+			/**< IPv6 destination address */
+			uint8_t dscp;
+			/**< IPv6 Differentiated Services Code Point */
+			uint32_t flabel;
+			/**< IPv6 flow label */
+			uint8_t hlimit;
+			/**< IPv6 hop limit */
+		} ipv6; /**< IPv6 header parameters */
+	}; /**< Various tunnel parameters */
+};
+
+/**
+ * IPSEC SA option flags
+ */
+struct rte_security_ipsec_sa_options {
+	/** Extended Sequence Numbers (ESN)
+	  *
+	  * * 1: Use extended (64 bit) sequence numbers
+	  * * 0: Use normal sequence numbers
+	  */
+	uint32_t esn : 1;
+
+	/** UDP encapsulation
+	  *
+	  * * 1: Do UDP encapsulation/decapsulation so that IPSEC packets can
+	  *      traverse through NAT boxes.
+	  * * 0: No UDP encapsulation
+	  */
+	uint32_t udp_encap : 1;
+
+	/** Copy DSCP bits
+	  *
+	  * * 1: Copy IPv4 or IPv6 DSCP bits from inner IP header to
+	  *      the outer IP header in encapsulation, and vice versa in
+	  *      decapsulation.
+	  * * 0: Use values from odp_ipsec_tunnel_param_t in encapsulation and
+	  *      do not change DSCP field in decapsulation.
+	  */
+	uint32_t copy_dscp : 1;
+
+	/** Copy IPv6 Flow Label
+	  *
+	  * * 1: Copy IPv6 flow label from inner IPv6 header to the
+	  *      outer IPv6 header.
+	  * * 0: Use value from odp_ipsec_tunnel_param_t
+	  */
+	uint32_t copy_flabel : 1;
+
+	/** Copy IPv4 Don't Fragment bit
+	  *
+	  * * 1: Copy the DF bit from the inner IPv4 header to the outer
+	  *      IPv4 header.
+	  * * 0: Use value from odp_ipsec_tunnel_param_t
+	  */
+	uint32_t copy_df : 1;
+
+	/** Decrement inner packet Time To Live (TTL) field
+	  *
+	  * * 1: In tunnel mode, decrement inner packet IPv4 TTL or
+	  *      IPv6 Hop Limit after tunnel decapsulation, or before tunnel
+	  *      encapsulation.
+	  * * 0: Inner packet is not modified.
+	  */
+	uint32_t dec_ttl : 1;
+
+};
+
+/** IPSec Operations */
+enum rte_security_ipsec_operation {
+	RTE_SECURITY_IPSEC_OP_ENCAP,
+	/**< Encrypt and generate digest */
+	RTE_SECURITY_IPSEC_OP_DECAP,
+	/**< Verify digest and decrypt */
+};
+
+/**
+ * IPSec Setup Data.
+ *
+ * This structure contains data relating to IPSec
+ * used to create a session.
+ */
+struct rte_security_ipsec_xform {
+	enum rte_security_ipsec_operation op;
+	/**< IPSec operation - Encap or Decap */
+	unsigned int spi;
+	/**< SA security parameter index */
+	enum rte_crypto_cipher_algorithm cipher_alg;
+	/**< Cipher Algorithm */
+	struct {
+		uint8_t *data;  /**< pointer to key data */
+		size_t length;   /**< key length in bytes */
+	} cipher_key;
+	enum rte_crypto_auth_algorithm auth_alg;
+	/**< Authentication Algorithm */
+	struct {
+		uint8_t *data;  /**< pointer to key data */
+		size_t length;   /**< key length in bytes */
+	} auth_key;
+	uint32_t salt;	/**< salt for this SA */
+	enum rte_security_conf_ipsec_sa_mode mode;
+	/**< IPsec SA Mode - transport/tunnel */
+	enum rte_security_conf_ipsec_sa_protocol proto;
+	/**< IPsec SA Protocol - AH/ESP */
+	struct rte_security_ipsec_tunnel_param tunnel;
+	/**< Tunnel parameters, NULL for transport mode */
+	struct rte_security_ipsec_sa_options options;
+	/**< various SA options */
+};
+
+/** IPsec Security Session Configuration */
+struct rte_security_dtls_xform {
+	/** To be Filled */
+};
+
+/** IPsec Security Session Configuration */
+struct rte_security_macsec_xform {
+	/** To be Filled */
+};
+
+/**< Security Session action type */
+enum rte_security_session_action_type {
+	RTE_SECURITY_SESS_NONE,
+	/**< Non protocol offload. Application need to manage everything */
+	RTE_SECURITY_SESS_ETH_INLINE_CRYPTO,
+	/**< Crypto operations are performed by Network interface */
+	RTE_SECURITY_SESS_ETH_PROTO_OFFLOAD,
+	/**< Crypto operations with protocol support are performed
+	 * by Network/ethernet device.
+	 */
+	RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD,
+	/**< Crypto operations with protocol support are performed
+	 * by Crypto device.
+	 */
+};
+
+/** Security Session Protocols */
+enum rte_security_sess_protocol {
+	RTE_SEC_CONF_DTLS,
+	/**< DTLS Protocol */
+	RTE_SEC_CONF_IPSEC,
+	/**< IPSec Protocol */
+	RTE_SEC_CONF_MACSEC,
+	/**< MACSec Protocol */
+};
+
+/**
+ * Security Session Configuration
+ */
+struct rte_security_sess_conf {
+	enum rte_security_session_action_type action_type;
+	/**< Type of action to be performed on the session */
+	enum rte_security_sess_protocol protocol;
+	/**< Security protocol to be configured */
+
+	union {
+		struct rte_security_ipsec_xform *ipsec_xform;
+		struct rte_security_dtls_xform *dtls_xform;
+		struct rte_security_macsec_xform *macsec_xform;
+	};
+	/**< Configuration parameters for security session */
+};
+
+struct rte_security_session {
+	__extension__ void *sess_private_data[0];
+	/**< Private session material */
+};
+
+/**
+ * Create Security session header (generic with no private data)
+ *
+ * @param   mempool    Session mempool to allocate session objects from
+ * @return
+ *  - On success, pointer to session
+ *  - On failure, NULL
+ */
+struct rte_security_session *
+rte_security_session_create(struct rte_mempool *mempool);
+
+/**
+ * Fill out private data for the device, based on its device id and name.
+ *
+ * @param   dev_id   Device id that we want the session to be used on
+ * @param   dev_name Device name for which session is to be used
+ * @param   sess     Session where the private data will be attached to
+ * @param   conf     Security config to apply on flow
+ *                   processed with this session
+ * @param   mempool  Mempool where the private data is allocated.
+ *
+ * @return
+ *  - On success, zero.
+ *  - On failure, a negative value.
+ */
+int
+rte_security_session_init(uint16_t dev_id,
+			  struct rte_security_session *sess,
+			  struct rte_security_sess_conf *conf,
+			  struct rte_mempool *mempool);
+
+/**
+ * Frees Security 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_security_session_free(struct rte_security_session *sess);
+
+/**
+ * Frees private data for the device id, based on its device name,
+ * returning it to its mempool.
+ *
+ * @param   dev_id	ID of device that uses the session.
+ * @param   action_type	Action type for Security operation.
+ * @param   sess	Session containing the reference to the private data
+ *
+ * @return
+ *  - 0 if successful.
+ *  - -EINVAL if device is invalid or session is NULL.
+ */
+int
+rte_security_session_clear(uint8_t dev_id,
+			   enum rte_security_session_action_type action_type,
+			   struct rte_security_session *sess);
+
+/**
+ * Attach a session to a symmetric crypto operation
+ *
+ * @param	sym_op	crypto operation
+ * @param	sess	security session
+ */
+static inline int
+__rte_security_attach_session(struct rte_crypto_sym_op *sym_op,
+			      struct rte_security_session *sess)
+{
+	sym_op->sec_session = sess;
+
+	return 0;
+}
+
+static inline void *
+get_sec_session_private_data(const struct rte_security_session *sess,
+		uint8_t driver_id) {
+	return sess->sess_private_data[driver_id];
+}
+
+static inline void
+set_sec_session_private_data(struct rte_security_session *sess,
+		uint8_t driver_id, void *private_data)
+{
+	sess->sess_private_data[driver_id] = private_data;
+}
+
+/**
+ * Attach a session to a crypto operation.
+ * This API is needed only in case of RTE_SECURITY_SESS_CRYPTO_PROTO_OFFLOAD
+ * For other rte_security_session_action_type, ol_flags in rte_mbuf may be
+ * defined to perform security operations.
+ *
+ * @param	op	crypto operation
+ * @param	sess	security session
+ */
+static inline int
+rte_security_attach_session(struct rte_crypto_op *op,
+			    struct rte_security_session *sess)
+{
+	if (unlikely(op->type != RTE_CRYPTO_OP_TYPE_SYMMETRIC))
+		return -1;
+
+	op->sess_type = RTE_CRYPTO_OP_WITH_SESSION;
+
+	return __rte_security_attach_session(op->sym, sess);
+}
+
+/**
+ * Security Capability
+ */
+struct rte_security_capabilities {
+	enum rte_security_sess_protocol protocol;
+	RTE_STD_C11
+	union {
+		struct {
+			enum rte_crypto_auth_algorithm a_algo;
+			/**< authentication algorithm */
+			enum rte_crypto_cipher_algorithm c_algo;
+			/**< cipher algorithm */
+			uint16_t block_size;
+			/**< algorithm block size */
+			struct rte_crypto_param_range c_key_size;
+			/**< cipher key size range */
+			struct rte_crypto_param_range a_key_size;
+			/**< auth key size range */
+			struct rte_crypto_param_range digest_size;
+			/**< digest size range */
+			struct rte_crypto_param_range iv_size;
+			/**< Initialisation vector data size range */
+		} ipsec;
+		/**< IPSEC transform capabilities */
+		struct {
+			/* To be Filled */
+		} dtls;
+		/**< DTLS transform capabilities */
+		struct {
+			/* To be Filled */
+		} macsec;
+		/**< MACSEC transform capabilities */
+	};
+};
+
+/**
+ *  Provide capabilities available for defined device and algorithm
+ *
+ * @param	dev_id		The identifier of the device.
+ * @param	dev_name	Device name for which capability is needed
+ * @param	protocol	Protocol for which capability is required
+ *
+ * @return
+ *   - Return description of the security capability if exist.
+ *   - Return NULL if the capability not exist.
+ */
+const struct rte_security_capabilities *
+rte_security_capability_get(uint8_t dev_id, char *dev_name,
+		enum rte_security_sess_protocol protocol);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_SECURITY_H_ */