diff mbox

[RFCv2] api:crypto: Adding IPSEC protocol APIs.

Message ID 20161024170454.29245-1-nikhil.agarwal@linaro.org
State New
Headers show

Commit Message

Nikhil Agarwal Oct. 24, 2016, 5:04 p.m. UTC
This RFC introduces IPSEC crypto offload APIs. These APIs can be used in accelerator
pipeline model or for look aside IPSEC model.

TODO items:
- statistics amd capability APIs
- Encrypt and send APIs

Signed-off-by: Nikhil Agarwal <nikhil.agarwal@linaro.org>

---
 include/odp/api/spec/crypto.h                      |  29 ++
 include/odp/api/spec/crypto_ipsec.h                | 449 +++++++++++++++++++++
 .../include/odp/api/plat/event_types.h             |   1 +
 3 files changed, 479 insertions(+)
 create mode 100644 include/odp/api/spec/crypto_ipsec.h

-- 
2.9.3

Comments

Josep Puigdemont Oct. 24, 2016, 11:48 a.m. UTC | #1
On Mon, Oct 24, 2016 at 10:34:54PM +0530, Nikhil Agarwal wrote:
> This RFC introduces IPSEC crypto offload APIs. These APIs can be used in accelerator

> pipeline model or for look aside IPSEC model.

> 

> TODO items:

> - statistics amd capability APIs

> - Encrypt and send APIs

> 

> Signed-off-by: Nikhil Agarwal <nikhil.agarwal@linaro.org>

> ---

>  include/odp/api/spec/crypto.h                      |  29 ++

>  include/odp/api/spec/crypto_ipsec.h                | 449 +++++++++++++++++++++

>  .../include/odp/api/plat/event_types.h             |   1 +

>  3 files changed, 479 insertions(+)

>  create mode 100644 include/odp/api/spec/crypto_ipsec.h

> 

> diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h

> index dea1fe9..3a67d92 100644

> --- a/include/odp/api/spec/crypto.h

> +++ b/include/odp/api/spec/crypto.h

> @@ -144,6 +144,27 @@ typedef union odp_crypto_auth_algos_t {

>  	uint32_t all_bits;

>  } odp_crypto_auth_algos_t;

>  

> +

> +/**

> + * Network security protocols in bit field structure

> + */

> +typedef union odp_crypto_protocol_t {

> +	/** Network security protocols */

> +	struct {

> +		/** ESP Protocol */

> +		uint32_t ipsec_esp    : 1;

> +

> +		/** AH protocol */

> +		uint32_t ipsec_ah     : 1;

> +

> +	} bit;

> +

> +	/** All bits of the bit field structure

> +	  *

> +	  * This field can be used to set/clear all flags, or bitwise

> +	  * operations over the entire structure. */

> +	uint32_t all_bits;

> +} odp_crypto_protocol_t;

>  /**

>   * Crypto API key structure

>   */

> @@ -264,6 +285,8 @@ typedef enum {

>  	ODP_CRYPTO_SES_CREATE_ERR_INV_CIPHER,

>  	/** Creation failed, bad auth params */

>  	ODP_CRYPTO_SES_CREATE_ERR_INV_AUTH,

> +	/** Creation failed, bad protocol params */

> +	ODP_CRYPTO_SES_CREATE_ERR_INV_PROTO,

>  } odp_crypto_ses_create_err_t;

>  

>  /**

> @@ -332,6 +355,12 @@ typedef struct odp_crypto_capability_t {

>  	/** Authentication algorithms implemented with HW offload */

>  	odp_crypto_auth_algos_t   hw_auths;

>  

> +	/** Supported authentication algorithms */

> +	odp_crypto_protocol_t   protocols;

> +

> +	/** Authentication algorithms implemented with HW offload */

> +	odp_crypto_protocol_t   hw_protocols;

> +

>  } odp_crypto_capability_t;

>  

>  /**

> diff --git a/include/odp/api/spec/crypto_ipsec.h b/include/odp/api/spec/crypto_ipsec.h

> new file mode 100644

> index 0000000..5916ea0

> --- /dev/null

> +++ b/include/odp/api/spec/crypto_ipsec.h

> @@ -0,0 +1,449 @@

> +/* Copyright (c) 2014, Linaro Limited

> + * Copyright (c) 2015 - 2016 Freescale Semiconductor, Inc.

> + * All rights reserved.

> + *

> + * SPDX-License-Identifier:	BSD-3-Clause

> + */

> +

> +/**

> + * @file

> + *

> + * ODP crypto IPSec extension

> + */

> +

> +#ifndef ODP_API_CRYPTO_IPSEC_H_

> +#define ODP_API_CRYPTO_IPSEC_H_

> +

> +#ifdef __cplusplus

> +extern "C" {

> +#endif

> +

> +

> +typedef enum odp_ipsec_mode {

> +	ODP_IPSEC_MODE_TUNNEL,	    /** IPSec tunnel mode */

> +	ODP_IPSEC_MODE_TRANSPORT,   /** IPSec transport mode */

> +} odp_ipsec_mode_t;

> +

> +typedef enum odp_ipsec_proto {

> +	ODP_IPSEC_ESP,		   /** ESP protocol */

> +	ODP_IPSEC_AH,		   /** AH protocol */

> +} odp_ipsec_proto_t;

> +

> +typedef enum odp_ipsec_outhdr_type {

> +	ODP_IPSEC_OUTHDR_IPV4,	  /** Outer header is IPv4 */

> +	ODP_IPSEC_OUTHDR_IPV6,	  /** Outer header is IPv6 */

> +} odp_ipsec_outhdr_type_t;

> +

> +/**

> +  * ODP IPSEC flags bit feilds structure

> +  */

> +

> +typedef struct odp_ipsec_session_flags {

> +	uint32_t esn : 1;

> +	/** When enabled, extended sequence numbers is used */

> +	uint32_t nat_t : 1;

> +	/** When enabled, this indicates that UDP encapsulation/decapsulation

> +	  * for IPSEC packet has to be done so that IPSEC packet can traverse

> +	  * through NAT boxes. UDP encapsulation/decapsulation is to be applied

> +	  * for packets that get processed off this SA.

> +	  */

> +	uint32_t copy_dscp : 1;

> +	/** When enabled, Copy the IPv4 TOS or IPv6 Traffic Class byte from

> +	  * inner/outer IP header to the outer/inner IP header. If disabled

> +	  * values from configured Header will be used */

> +	uint32_t copy_df : 1;

> +	/** When enabled, copy the DF bit from the inner IP header to the outer

> +	  * IP header. If disabled, values from configured Header will be used */

> +

> +	uint32_t ip_dttl : 1;

> +	/** When enabled,IPv4 ttl/IPv6 Hop Limit feild will be decremented

> +	  * in case of tunnel mode encap & decap */

> +

> +	uint32_t remove_outer_hdr : 1;

> +	/** remove outer header - tunnel mode decap */

> +

> +	uint32_t verify_sa_selectors : 1;

> +	/** This flag is only application to inbound sessions. When enabled,

> +	  * this indicates that post decryption, selectors needs to be verified

> +	  * for this session. */

> +

> +} odp_ipsec_session_flags_t;

> +

> +typedef enum odp_ipsec_sa_lifetime_type {

> +	ODP_IPSEC_SA_LIFETIME_IN_SEC, /** SA life time is in seconds */

> +	ODP_IPSEC_SA_LIFETIME_IN_KB,  /** SA life time is in kilo bytes */

> +	ODP_IPSEC_SA_LIFETIME_IN_PKT_CNT, /** SA life time is in packet count */

> +} odp_ipsec_sa_lifetime_type_t;

> +

> +typedef struct odp_ipsec_params {

> +	odp_ipsec_mode_t ipsec_mode; /** Transport or Tunnel */

> +	odp_ipsec_proto_t ipsec_proto; /** IPSEC protocol ESP/AH */

> +	uint64_t seq;		 /** Initial SEQ number */

> +	uint32_t spi;		 /** SPI value */

> +	uint16_t ar_ws; /** Anti-replay window size. Value 0 indicates that

> +			  Anti-replay window check is disabled for this SA */

> +	uint16_t out_hdr_size;	 /** outer header size - tunnel mode */

> +	uint8_t *out_hdr;	 /** outer header - tunnel mode */

> +	odp_ipsec_outhdr_type_t out_hdr_type; /** outer header type tunnel mode*/

> +	odp_ipsec_session_flags_t sa_flags; /** SA control flags */

> +	odp_ipsec_sa_lifetime_type_t lifetime_type; /** lifetime type */

> +	uint64_t soft_expiry_limit;

> +	/** Soft expiry for this session, values may be in seconds, Kilobytes or

> +	  * number of packets depending on feild odp_ipsec_sa_lifetime_type_t */

> +	uint64_t hard_expiry_limit;

> +	/** Hard expiry for this session, values may be in seconds, Kilobytes or

> +	  * number of packets depending on feild odp_ipsec_sa_lifetime_type_t */

> +

> +} odp_ipsec_params_t;

> +

> +/**

> + * Configure crypto session for IPsec processing

> + *

> + * Configures a crypto session for IPSec protocol processing.

> + * Packets submitted to an IPSec enabled session will have

> + * relevant IPSec headers/trailers and tunnel headers

> + * added/removed by the crypto implementation.

> + * For example, the input packet for an IPSec ESP transport

> + * enabled session should be the clear text packet with

> + * no ESP headers/trailers prepared in advance for crypto operation.

> + * The output packet will have ESP header, IV, trailer and the ESP ICV

> + * added by crypto implementation.

> + * Depending on the particular capabilities of an implementation and

> + * the parameters enabled by application, the application may be

> + * partially or completely offloaded from IPSec protocol processing.

> + * For example, if an implementation does not support checksum

> + * update for IP header after adding ESP header the application

> + * should update after crypto IPSec operation.

> + *

> + * If an implementation does not support a particular set of

> + * arguments it should return error.

> + *

> + * @param session	    Session handle

> + * @param ipsec_params	    IPSec parameters. Parameters which are not

> + *			    relevant for selected protocol & mode are ignored -

> + *			    e.g. outer_hdr/size set for ESP transport mode.

> + * @retval 0 on success

> + * @retval <0 on failure

> + */

> +int odp_crypto_ipsec_session_create(odp_crypto_session_params_t *ses_params,

> +				    odp_ipsec_params_t *ipsec_params,

> +				    odp_crypto_session_t *session_out,

> +				    odp_crypto_ses_create_err_t *status);

> +

> +

> +/**

> + * SPD Policy/SA direction information

> + */

> +typedef enum odp_ipsec_direction {

> +	ODP_IPSEC_INBOUND, 	/** Inbound Direction */

> +	ODP_IPSEC_OUTBOUND 	/** Outbound Direction */

> +}odp_ipsec_direction_t;

> +

> +/**

> + * SPD Policy Action information

> + */

> +typedef enum odp_ipsec_policy_rule_action {

> +	ODP_IPSEC_POLICY_ACTION_IPSEC, /** Apply IPSec processing on Packet*/

> +	ODP_IPSEC_POLICY_ACTION_DISCARD, /** Discard or Drop the packet */

> +	ODP_IPSEC_POLICY_ACTION_BYPASS, /** Bypass/Allow to pass the packet */

> +}odp_ipsec_policy_rule_action_t;

> +

> +/**

> + * SPD Policy Position information

> + */

> +typedef enum odp_ipsec_policy_rule_position{

> +	ODP_IPSEC_POLICY_POSITION_BEGIN, /** Add at the beginning of the list */

> +	ODP_IPSEC_POLICY_POSITION_BEFORE, /** Add before the mentioned Policy */

> +	ODP_IPSEC_POLICY_POSITION_AFTER, /** Add after the mentioned Policy */

> +	ODP_IPSEC_POLICY_POSITION_END, /** Add at the end of the list */

> +} odp_ipsec_policy_rule_position_t;

> +

> +

> +/**

> + * DSCP Range information

> + */

> +typedef struct odp_ipsec_policy_rule_dscprange {

> +	uint8_t start; 	/** Start value in Range */

> +	uint8_t end; 	/** End value  in Range */

> +}odp_ipsec_policy_rule_dscprange_t;

> +

> +/**

> + * Fragmentation Before Encapsulation (Redside Fragmentation)

> + */

> +typedef enum odp_ipsec_policy_redside_fragmentation {

> +	ODP_IPSEC_POLICY_REDSIDE_FRAGMENTATION_DISABLE = 0,

> +	/** Disable Redside fragmentation in IPSec Policy */

> +	ODP_IPSEC_POLICY_REDSIDE_FRAGMENTATION_ENABLE

> +		/** Enable Redside fragmentation in IPSec Policy */

> +}odp_ipsec_policy_redside_fragmentation_t;

> +

> +/**

> + * Input parameters to SPD Policy addition

> + */

> +struct odp_ipsec_spd_params{

> +	uint32_t tunnel_id;

> +	/** Tunnel ID */

> +	odp_ipsec_direction_t dir;

> +	/** Direction: Inbound or Outbound */

> +	odp_ipsec_policy_rule_action_t action;

> +	/** SPD Policy Action */

> +	odp_ipsec_policy_rule_position_t position;

> +	/** Position of this policy in policy table */

> +	odp_ipsec_policy_t relative_policy;

> +	/** relative policy for the position in case of before/after */

> +	uint32_t n_dscp_ranges;

> +	/** Number of DSCP Ranges */

> +	struct odp_ipsec_policy_rule_dscprange *dscp_ranges;

> +	/** Array of DSCP Ranges */

> +	enum odp_ipsec_policy_redside_fragmentation redside;

> +	/** Fragmentation before Encapsulation option: TRUE/FALSE */

> +	uint32_t n_selectors;

> +	/** Number of selectors */

> +	const odp_pmr_param_t *selectors;

> +	/** Array of Selectors */

> +};

> +

> +/**

> + * Output parameters to SPD Policy addition

> + */

> +typedef struct odp_ipsec_spd_add_err{

> +	int32_t result;

> +	/** 0:Success; Non Zero value: Error code indicating failure */

> +}odp_ipsec_pol_add_err_t;

> +

> +/**

> + * @brief This API is used to add Inbound/Outbound SPD policy to SPD policy

> + * database.  This database is maintained per Name Space and Tunnel instance.

> + * This function first validates the incoming parameters

> + * and if all validations succeed, new SPD policy is added to the database.

> + *

> + * @param[in] params	Pointer to input param structure which contains

> + *			spd policy information.

> + * @param[out] policy 	Handle to the IPSEC policy.

> + * @param[out] resp	Failure code if unsuccessful.

> + *

> + * @returns 0 on Success or negative value on failure.

> + *

> + */

> +int32_t odp_ipsec_spd_add(

> +		const struct odp_ipsec_spd_params *params,

> +		odp_ipsec_policy_t *policy,

> +		odp_ipsec_pol_add_err_t *resp);

> +

> +/**

> + * @brief This API is used to delete Inbound/Outbound SPD policy from SPD policy

> + * database.

> + *

> + * @param[in] policy 	Handle to the IPSEC policy.

> + *

> + * @returns 0 on Success or negative value on failure.

> + *

> + */

> +int32_t odp_ipsec_spd_del(odp_ipsec_policy_t policy);

> +

> +/**

> + * @brief This API is used to flush/delete all Inbound and Outbound SPD

> + * policies.

> + *

> + * @returns 0 on Success or negative value on failure.

> + *

> + */

> +int32_t odp_ipsec_spd_flush();

> +

> +/**

> + * @brief This API maps an IPSEC policy to an IPSEC crypto session.

> + *

> + * @param[in] policy - Handle to the IPSEC policy.

> + * @param[in] session - Handle to the IPSEC session(SA).

> + *

> + * @returns SUCCESS on success; FAILURE otherwise

> + *

> + */

> +int32_t odp_ipsec_map_pol_session(odp_ipsec_policy_t policy

> +		odp_crypto_session_t session);

> +

> +/**

> + * @brief This API unmaps an IPSEC policy to an IPSEC crypto session.

> + *

> + * @param[in] policy - Handle to the IPSEC policy.

> + * @param[in] session - Handle to the IPSEC session(SA).

> + *

> + * @returns SUCCESS on success; FAILURE otherwise

> + *

> + */

> +int32_t odp_ipsec_unmap_pol_session(odp_ipsec_policy_t policy

> +		odp_crypto_session_t session);

> +

> +/**

> +  * ODP ipsec notification event type

> +  */

> +

> +typedef enum odp_ipsec_notif_type {

> +	ODP_IPSEC_NO_OUB_SA, /** IPSEC policy matched but Outbound SA not found */

> +	ODP_IPSEC_NO_INB_SA, /** IPSEC policy matched but inbound SA not found */

> +	ODP_IPSEC_SA_SOFT_EXPIRY, /** SA soft expiry limit reached */

> +	ODP_IPSEC_SA_HARD_EXPIRY, /** SA hard expiry limit reached */

> +	ODP_IPSEC_SA_SEQ_NUM_OVERFLOW, /** Seq number overflow */

> +} odp_ipsec_notif_type_t;

> +

> +typedef struct odp_ipsec_notif_info {

> +	odp_ipsec_notif_type_t notif_type;

> +	odp_ipsec_policy_t policy;

> +	odp_ipsec_session_t session;

> +}odp_ipsec_notif_info_t;

> +

> +/**

> + * @brief This API gets notification queue for ODP IPSEC module.

> + *

> + * @param[out] queue - Handle to the IPSEC notification queue.

> + *

> + * @returns SUCCESS on success; FAILURE otherwise

> + *

> + */

> +int32_t odp_ipsec_get_notification_queue(odp_queue_t *queue);

> +

> +/**

> + * Return crypto notification handle that is associated with event

> + *

> + * Note: any invalid parameters will cause undefined behavior and may cause

> + * the application to abort or crash.

> + *

> + * @param ev An event of type ODP_EVENT_CRYPTO_NOTIF

> + *

> + * @return crypto completion handle

> + */

> +odp_crypto_notif_t odp_crypto_notif_from_event(odp_event_t ev);

> +

> +

> +/**

> + * Return notification info of this crypto notification event.

> + *

> + * @param[in] notif_ev An event of type ODP_EVENT_CRYPTO_NOTIF

> + * @param[out] notif_info structure populated with notification info

> + *

> + * @return success/failure

> + */

> +uint32_t odp_ipsec_notif_info_from_event(odp_crypto_notif_t notif_ev

> +		odp_ipsec_notif_info_t* notif_info);

> +

> +/**

> + * SPD Policy Statistics information structure

> + */

> +typedef struct odp_ipsec_spd_stats {

> +	uint64_t received_pkts;

> +	/** Received Outbound/Inbound packets */

> +	uint64_t processed_pkts;

> +	/** Processed Outbound/Inbound packets */

> +	uint64_t processed_bytes;

> +	/** Number of bytes processed on Inbound/Outbound policy */

> +

> +	/** Struct details

> +	 */

> +	struct {

> +		uint32_t crypto_op_failed;

> +		/** Crypto operations failed */

> +	}protocol_violation_errors;

> +	/** Protocol violation errors */

> +

> +	/** Struct details

> +	 */

> +	struct {

> +		uint32_t no_matching_dscp_range;

> +		/** Matching dscp range not found in the SPD policy */

> +

> +		uint32_t submit_to_sec_failed;

> +		/** Submission to SEC failed for crypto operations */

> +		uint32_t no_outb_sa;

> +		/** Outbound SA not found */

> +		uint32_t frag_failed;

> +		/** Fragmentation failed */

> +		uint32_t mem_alloc_failed;

> +		/** Memory allocation failed for SA/SPD/descriptor etc.*/

> +		uint32_t internal_error;

> +		/** All other errors locally encountered */

> +	}local_errors;

> +	/** Local/internal errors */

> +

> +}odp_ipsec_spd_stats_t;

> +

> +/**

> + * @brief This API fetches global statistics.

> + *

> + * @param[out] stats  Pointer to statistics structure filled by this API.

> + *

> + * @returns 0 on Success or negative value on failure.

> + *

> + */

> +int32_t odp_ipsec_global_stats_get(odp_ipsec_spd_stats_t *stats);

> +

> +/**

> + * IPSec Module Capabilities

> + */

> +struct odp_ipsec_capabilities {

> +	/** This parameter indicates if IPSec-DP is capable of doing SPD

> +	 * rule search for incoming or outgoing datagrams

> +	 */

> +

> +	uint32_t sel_store_in_spd : 1,

> +

> +		 /** Authentication Header processing */

> +		 ah_protocol:1,

> +

> +		 /** ESP Header processing */

> +		 esp_protocol:1,

> +

> +		 /** IPComp related processing */

> +		 ipcomp_protocol:1,

> +

> +		 /** IPSec Tunnel Mode processing */

> +		 tunnel_mode:1,

> +

> +		 /** IPSec Tunnel Mode processing */

> +		 transport_mode:1,

> +

> +		 /** This indicates if IPSec has capability to generate

> +		  * (for Outbound) and verify (for Inbound) extended sequence numbers.

> +		  */

> +		 esn:1,

> +

> +		 /** This option indicates whether IPSec can

> +		  * handle the necessary UDP Encapsulation required at

> +		  * IPSec level for traversing NAT boxes.

> +		  */

> +		 udp_encap:1,

> +

> +		 /** This option indicates whether IPSec can fragment packets

> +		  * before IPSec encryption, so that the resulting IPSec encrypted

> +		  * fragments do not exceed MTU

> +		  */

> +		 redside_frag:1,

> +

> +

> +	/** Indicates the maximum number of IN and OUT SPD policies. */

> +	uint32_t	    max_spd_policies;

> +

> +	/** Indicates the maximum number of IN and OUT IPSec SAs. */

> +	uint32_t	     max_sas;

> +}odp_ipsec_capabilities_t;

> +

> +/**

> + * @brief This API fetches IPSec module Capabilities

> + *

> + * @param[out] capa - capabilities structure filled by API.

> + *

> + * @returns SUCCESS on success; FAILURE otherwise

> + *

> + */

> +int32_t odp_ipsec_capabilities_get(odp_ipsec_capabilities_t *capa);

> +

> +

> +#endif /* __IPSEC_API_H */

> +/**

> + * @}

> + */

> +

> +#ifdef __cplusplus

> +}

> +#endif

> +

> +#endif

> diff --git a/platform/linux-generic/include/odp/api/plat/event_types.h b/platform/linux-generic/include/odp/api/plat/event_types.h

> index 9ca0fb8..b083d3e 100644

> --- a/platform/linux-generic/include/odp/api/plat/event_types.h

> +++ b/platform/linux-generic/include/odp/api/plat/event_types.h

> @@ -38,6 +38,7 @@ typedef enum odp_event_type_t {

>  	ODP_EVENT_PACKET       = 2,

>  	ODP_EVENT_TIMEOUT      = 3,

>  	ODP_EVENT_CRYPTO_COMPL = 4,

> +	ODP_EVENT_CRYPTO_notif = 5,


Should probably be in capital letters :-)

>  } odp_event_type_t;

>  

>  /** Get printable format of odp_event_t */

> -- 

> 2.9.3

>
Bill Fischofer Oct. 26, 2016, 2:55 a.m. UTC | #2
On Mon, Oct 24, 2016 at 12:04 PM, Nikhil Agarwal <nikhil.agarwal@linaro.org>
wrote:

> This RFC introduces IPSEC crypto offload APIs. These APIs can be used in

> accelerator

> pipeline model or for look aside IPSEC model.

>

> TODO items:

> - statistics amd capability APIs

> - Encrypt and send APIs

>

> Signed-off-by: Nikhil Agarwal <nikhil.agarwal@linaro.org>

> ---

>  include/odp/api/spec/crypto.h                      |  29 ++

>  include/odp/api/spec/crypto_ipsec.h                | 449

> +++++++++++++++++++++

>  .../include/odp/api/plat/event_types.h             |   1 +

>  3 files changed, 479 insertions(+)

>  create mode 100644 include/odp/api/spec/crypto_ipsec.h

>

> diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h

> index dea1fe9..3a67d92 100644

> --- a/include/odp/api/spec/crypto.h

> +++ b/include/odp/api/spec/crypto.h

> @@ -144,6 +144,27 @@ typedef union odp_crypto_auth_algos_t {

>         uint32_t all_bits;

>  } odp_crypto_auth_algos_t;

>

> +

> +/**

> + * Network security protocols in bit field structure

> + */

> +typedef union odp_crypto_protocol_t {

> +       /** Network security protocols */

> +       struct {

> +               /** ESP Protocol */

> +               uint32_t ipsec_esp    : 1;

> +

> +               /** AH protocol */

> +               uint32_t ipsec_ah     : 1;

> +

> +       } bit;

> +

> +       /** All bits of the bit field structure

> +         *

> +         * This field can be used to set/clear all flags, or bitwise

> +         * operations over the entire structure. */

> +       uint32_t all_bits;

> +} odp_crypto_protocol_t;

>  /**

>   * Crypto API key structure

>   */

> @@ -264,6 +285,8 @@ typedef enum {

>         ODP_CRYPTO_SES_CREATE_ERR_INV_CIPHER,

>         /** Creation failed, bad auth params */

>         ODP_CRYPTO_SES_CREATE_ERR_INV_AUTH,

> +       /** Creation failed, bad protocol params */

> +       ODP_CRYPTO_SES_CREATE_ERR_INV_PROTO,

>  } odp_crypto_ses_create_err_t;

>

>  /**

> @@ -332,6 +355,12 @@ typedef struct odp_crypto_capability_t {

>         /** Authentication algorithms implemented with HW offload */

>         odp_crypto_auth_algos_t   hw_auths;

>

> +       /** Supported authentication algorithms */

> +       odp_crypto_protocol_t   protocols;

> +

> +       /** Authentication algorithms implemented with HW offload */

> +       odp_crypto_protocol_t   hw_protocols;

> +

>  } odp_crypto_capability_t;

>

>  /**

> diff --git a/include/odp/api/spec/crypto_ipsec.h

> b/include/odp/api/spec/crypto_ipsec.h

> new file mode 100644

> index 0000000..5916ea0

> --- /dev/null

> +++ b/include/odp/api/spec/crypto_ipsec.h

> @@ -0,0 +1,449 @@

> +/* Copyright (c) 2014, Linaro Limited

> + * Copyright (c) 2015 - 2016 Freescale Semiconductor, Inc.

>


Linaro copyright should be 2016, not 2014.
Freescale copyright should be 2016, not 2015. Should this also be NXP here?


> + * All rights reserved.

> + *

> + * SPDX-License-Identifier:    BSD-3-Clause

> + */

> +

> +/**

> + * @file

> + *

> + * ODP crypto IPSec extension

>


We need to be consistent with how this acronym is written. The proper
spelling/case is IPsec, per the normative reference RFC 4301 and addenda.
No other case variants should be used in documentation. All caps IPSEC is
fine in enums and #defines when used in code. All lower case ipsec is fine
in api names.


> + */

> +

> +#ifndef ODP_API_CRYPTO_IPSEC_H_

> +#define ODP_API_CRYPTO_IPSEC_H_

> +

> +#ifdef __cplusplus

> +extern "C" {

> +#endif

> +

> +

> +typedef enum odp_ipsec_mode {

> +       ODP_IPSEC_MODE_TUNNEL,      /** IPSec tunnel mode */

> +       ODP_IPSEC_MODE_TRANSPORT,   /** IPSec transport mode */

> +} odp_ipsec_mode_t;

> +

> +typedef enum odp_ipsec_proto {

> +       ODP_IPSEC_ESP,             /** ESP protocol */

> +       ODP_IPSEC_AH,              /** AH protocol */

> +} odp_ipsec_proto_t;

> +

> +typedef enum odp_ipsec_outhdr_type {

> +       ODP_IPSEC_OUTHDR_IPV4,    /** Outer header is IPv4 */

> +       ODP_IPSEC_OUTHDR_IPV6,    /** Outer header is IPv6 */

> +} odp_ipsec_outhdr_type_t;

> +

> +/**

> +  * ODP IPSEC flags bit feilds structure

> +  */

> +

> +typedef struct odp_ipsec_session_flags {

> +       uint32_t esn : 1;

> +       /** When enabled, extended sequence numbers is used */

> +       uint32_t nat_t : 1;

> +       /** When enabled, this indicates that UDP

> encapsulation/decapsulation

> +         * for IPSEC packet has to be done so that IPSEC packet can

> traverse

> +         * through NAT boxes. UDP encapsulation/decapsulation is to be

> applied

> +         * for packets that get processed off this SA.

> +         */

> +       uint32_t copy_dscp : 1;

> +       /** When enabled, Copy the IPv4 TOS or IPv6 Traffic Class byte from

> +         * inner/outer IP header to the outer/inner IP header. If disabled

> +         * values from configured Header will be used */

> +       uint32_t copy_df : 1;

> +       /** When enabled, copy the DF bit from the inner IP header to the

> outer

> +         * IP header. If disabled, values from configured Header will be

> used */

> +

> +       uint32_t ip_dttl : 1;

> +       /** When enabled,IPv4 ttl/IPv6 Hop Limit feild will be decremented

> +         * in case of tunnel mode encap & decap */

> +

> +       uint32_t remove_outer_hdr : 1;

> +       /** remove outer header - tunnel mode decap */

> +

> +       uint32_t verify_sa_selectors : 1;

> +       /** This flag is only application to inbound sessions. When

> enabled,

> +         * this indicates that post decryption, selectors needs to be

> verified

> +         * for this session. */

> +

>


No blank line here (checkpatch)


> +} odp_ipsec_session_flags_t;

> +

> +typedef enum odp_ipsec_sa_lifetime_type {

> +       ODP_IPSEC_SA_LIFETIME_IN_SEC, /** SA life time is in seconds */

> +       ODP_IPSEC_SA_LIFETIME_IN_KB,  /** SA life time is in kilo bytes */

> +       ODP_IPSEC_SA_LIFETIME_IN_PKT_CNT, /** SA life time is in packet

> count */

> +} odp_ipsec_sa_lifetime_type_t;

>


As noted during today's public call, we need to be able to specify a
lifetime to be whichever comes first: a specified number of bytes used by
this SA, or an elapsed number of seconds.


> +

> +typedef struct odp_ipsec_params {

> +       odp_ipsec_mode_t ipsec_mode; /** Transport or Tunnel */

> +       odp_ipsec_proto_t ipsec_proto; /** IPSEC protocol ESP/AH */

> +       uint64_t seq;            /** Initial SEQ number */

> +       uint32_t spi;            /** SPI value */

> +       uint16_t ar_ws; /** Anti-replay window size. Value 0 indicates that

> +                         Anti-replay window check is disabled for this SA

> */

> +       uint16_t out_hdr_size;   /** outer header size - tunnel mode */

> +       uint8_t *out_hdr;        /** outer header - tunnel mode */

> +       odp_ipsec_outhdr_type_t out_hdr_type; /** outer header type tunnel

> mode*/

> +       odp_ipsec_session_flags_t sa_flags; /** SA control flags */

> +       odp_ipsec_sa_lifetime_type_t lifetime_type; /** lifetime type */

> +       uint64_t soft_expiry_limit;

> +       /** Soft expiry for this session, values may be in seconds,

> Kilobytes or

> +         * number of packets depending on feild

> odp_ipsec_sa_lifetime_type_t */

> +       uint64_t hard_expiry_limit;

> +       /** Hard expiry for this session, values may be in seconds,

> Kilobytes or

> +         * number of packets depending on feild

> odp_ipsec_sa_lifetime_type_t */

>


Need to clarify what soft and hard limits mean here. I'm assuming that when
the soft limit is hit, a notification is sent so that rekeying processing
can begin while the old keys continue to be used. When the hard limit is
hit, the SA is invalidated so any further attempts to use it will fail.


> +

>


No blank line here (checkpatch)


> +} odp_ipsec_params_t;

>


Other param structs in ODP (odp_pool_param_t, odp_queue_param_t,
odp_pktin_queue_param_t, etc. all use the singular param rather than
params. We should follow this model here so this should be
odp_ipsec_param_t. We should also probably change
odp_crypto_session_params_t to odp_crypto_session_param_t and
odp_crypto_op_params_t to odp_crypto_op_param_t as well for consistency as
a separate API change patch for Tiger Moth.

We also should have an odp_ipsec_param_init() API to initialize this to a
default state for consistency with other param structs. And add
corresponding init() APIs for odp_crypto_session_param_t and
odp_crypto_op_param_t as well.


> +

> +/**

> + * Configure crypto session for IPsec processing

> + *

> + * Configures a crypto session for IPSec protocol processing.

> + * Packets submitted to an IPSec enabled session will have

> + * relevant IPSec headers/trailers and tunnel headers

> + * added/removed by the crypto implementation.

> + * For example, the input packet for an IPSec ESP transport

> + * enabled session should be the clear text packet with

> + * no ESP headers/trailers prepared in advance for crypto operation.

> + * The output packet will have ESP header, IV, trailer and the ESP ICV

> + * added by crypto implementation.

> + * Depending on the particular capabilities of an implementation and

> + * the parameters enabled by application, the application may be

> + * partially or completely offloaded from IPSec protocol processing.

> + * For example, if an implementation does not support checksum

> + * update for IP header after adding ESP header the application

> + * should update after crypto IPSec operation.

> + *

> + * If an implementation does not support a particular set of

> + * arguments it should return error.

> + *

> + * @param session          Session handle

>


Inconsistent. This is specified as ses_params in the API below. Pick one.
Larger question is should this be specified as a field within the
odp_ipsec_param_t struct? What's the use case for separating these two so
that the same odp_ipsec_param_t can be used with different
odp_crypto_session_param_t's?


> + * @param ipsec_params     IPSec parameters. Parameters which are not

> + *                         relevant for selected protocol & mode are

> ignored -

> + *                         e.g. outer_hdr/size set for ESP transport mode.

>


You're missing @param info for the other two parameters (session_out,
status)


> + * @retval 0 on success

> + * @retval <0 on failure

> + */

> +int odp_crypto_ipsec_session_create(odp_crypto_session_params_t

> *ses_params,

> +                                   odp_ipsec_params_t *ipsec_params,


+                                   odp_crypto_session_t *session_out,
>


Should this be an overload of the existing odp_crypto_session_t type?
Should this be a new odp_ipsec_session_t or odp_ipsec_session_t type?


> +                                   odp_crypto_ses_create_err_t *status);

>


again, should this be an overload or a new type
(odp_ipsec_ses_create_err_t)?


> +

> +

> +/**

> + * SPD Policy/SA direction information

> + */

> +typedef enum odp_ipsec_direction {

> +       ODP_IPSEC_INBOUND,      /** Inbound Direction */

> +       ODP_IPSEC_OUTBOUND      /** Outbound Direction */

> +}odp_ipsec_direction_t;

>


space after } (checkpatch)


> +

> +/**

> + * SPD Policy Action information

> + */

> +typedef enum odp_ipsec_policy_rule_action {

> +       ODP_IPSEC_POLICY_ACTION_IPSEC, /** Apply IPSec processing on

> Packet*/

> +       ODP_IPSEC_POLICY_ACTION_DISCARD, /** Discard or Drop the packet */

> +       ODP_IPSEC_POLICY_ACTION_BYPASS, /** Bypass/Allow to pass the

> packet */

> +}odp_ipsec_policy_rule_action_t;

>


space after } (checkpatch)


> +

> +/**

> + * SPD Policy Position information

> + */

> +typedef enum odp_ipsec_policy_rule_position{

>


space before { (checkpatch)


> +       ODP_IPSEC_POLICY_POSITION_BEGIN, /** Add at the beginning of the

> list */

> +       ODP_IPSEC_POLICY_POSITION_BEFORE, /** Add before the mentioned

> Policy */

> +       ODP_IPSEC_POLICY_POSITION_AFTER, /** Add after the mentioned

> Policy */

> +       ODP_IPSEC_POLICY_POSITION_END, /** Add at the end of the list */

> +} odp_ipsec_policy_rule_position_t;

> +

> +

> +/**

> + * DSCP Range information

> + */

> +typedef struct odp_ipsec_policy_rule_dscprange {

> +       uint8_t start;  /** Start value in Range */

> +       uint8_t end;    /** End value  in Range */

> +}odp_ipsec_policy_rule_dscprange_t;

>


space after } (checkpatch)


> +

> +/**

> + * Fragmentation Before Encapsulation (Redside Fragmentation)

> + */

> +typedef enum odp_ipsec_policy_redside_fragmentation {

> +       ODP_IPSEC_POLICY_REDSIDE_FRAGMENTATION_DISABLE = 0,

> +       /** Disable Redside fragmentation in IPSec Policy */

> +       ODP_IPSEC_POLICY_REDSIDE_FRAGMENTATION_ENABLE

> +               /** Enable Redside fragmentation in IPSec Policy */

> +}odp_ipsec_policy_redside_fragmentation_t;

>


space after } (checkpatch)


> +

> +/**

> + * Input parameters to SPD Policy addition

> + */

> +struct odp_ipsec_spd_params{



space before { (checkpatch)
Why is this not a typedef? Should be for type odp_ipsec_spd_param_t (no
plural). Also means we need an odp_ipsec_spd_param_init() API for
completeness.


> +       uint32_t tunnel_id;

> +       /** Tunnel ID */

> +       odp_ipsec_direction_t dir;

> +       /** Direction: Inbound or Outbound */

> +       odp_ipsec_policy_rule_action_t action;

> +       /** SPD Policy Action */

> +       odp_ipsec_policy_rule_position_t position;

> +       /** Position of this policy in policy table */

> +       odp_ipsec_policy_t relative_policy;

>


odp_ipsec_policy_t does not appear to be defined here. It's also referenced
in several APIs below.


> +       /** relative policy for the position in case of before/after */

> +       uint32_t n_dscp_ranges;

> +       /** Number of DSCP Ranges */

> +       struct odp_ipsec_policy_rule_dscprange *dscp_ranges;

> +       /** Array of DSCP Ranges */

> +       enum odp_ipsec_policy_redside_fragmentation redside;

> +       /** Fragmentation before Encapsulation option: TRUE/FALSE */

> +       uint32_t n_selectors;

> +       /** Number of selectors */

> +       const odp_pmr_param_t *selectors;

> +       /** Array of Selectors */

> +};

> +

> +/**

> + * Output parameters to SPD Policy addition

> + */

> +typedef struct odp_ipsec_spd_add_err{

>


space before { (checkpatch)


> +       int32_t result;

> +       /** 0:Success; Non Zero value: Error code indicating failure */

> +}odp_ipsec_pol_add_err_t;

>


space after } (checkpatch)

Does this need to be a struct? Do we expect to expand this? Seems
cumbersome if the only output is a simple return code.


> +

> +/**

> + * @brief This API is used to add Inbound/Outbound SPD policy to SPD

> policy

> + * database.  This database is maintained per Name Space and Tunnel

> instance.

> + * This function first validates the incoming parameters

> + * and if all validations succeed, new SPD policy is added to the

> database.

> + *

> + * @param[in] params   Pointer to input param structure which contains

> + *                     spd policy information.

> + * @param[out] policy  Handle to the IPSEC policy.

> + * @param[out] resp    Failure code if unsuccessful.

> + *

> + * @returns 0 on Success or negative value on failure.

> + *

> + */

> +int32_t odp_ipsec_spd_add(

> +               const struct odp_ipsec_spd_params *params,

>


should be const odp_ipsec_spd_param_t *params,


> +               odp_ipsec_policy_t *policy,

> +               odp_ipsec_pol_add_err_t *resp);

> +

> +/**

> + * @brief This API is used to delete Inbound/Outbound SPD policy from SPD

> policy

> + * database.

> + *

> + * @param[in] policy   Handle to the IPSEC policy.

> + *

> + * @returns 0 on Success or negative value on failure.

> + *

> + */

> +int32_t odp_ipsec_spd_del(odp_ipsec_policy_t policy);

> +

> +/**

> + * @brief This API is used to flush/delete all Inbound and Outbound SPD

> + * policies.

> + *

> + * @returns 0 on Success or negative value on failure.

> + *

> + */

> +int32_t odp_ipsec_spd_flush();

>


Syntax: must be odp_ipsec_spd_flush(void);


> +

> +/**

> + * @brief This API maps an IPSEC policy to an IPSEC crypto session.

> + *

> + * @param[in] policy - Handle to the IPSEC policy.

> + * @param[in] session - Handle to the IPSEC session(SA).

> + *

> + * @returns SUCCESS on success; FAILURE otherwise

> + *

> + */

> +int32_t odp_ipsec_map_pol_session(odp_ipsec_policy_t policy

>


pol is an awkward abbreviation. odp_ipsec_map_policy_session() would seem
to be preferable here.


> +               odp_crypto_session_t session);

>


See earlier comments regarding overload of odp_crypto_session_t type.

+
> +/**

> + * @brief This API unmaps an IPSEC policy to an IPSEC crypto session.

>


...from an IPsec crypto session


> + *

> + * @param[in] policy - Handle to the IPSEC policy.

> + * @param[in] session - Handle to the IPSEC session(SA).

> + *

> + * @returns SUCCESS on success; FAILURE otherwise

> + *

> + */

> +int32_t odp_ipsec_unmap_pol_session(odp_ipsec_policy_t policy

>


Again, odp_ipsec_unmap_policy_session()


> +               odp_crypto_session_t session);

>


Same question on overload of this type.


> +

> +/**

> +  * ODP ipsec notification event type

> +  */

> +

> +typedef enum odp_ipsec_notif_type {

> +       ODP_IPSEC_NO_OUB_SA, /** IPSEC policy matched but Outbound SA not

> found */

> +       ODP_IPSEC_NO_INB_SA, /** IPSEC policy matched but inbound SA not

> found */

> +       ODP_IPSEC_SA_SOFT_EXPIRY, /** SA soft expiry limit reached */

> +       ODP_IPSEC_SA_HARD_EXPIRY, /** SA hard expiry limit reached */

> +       ODP_IPSEC_SA_SEQ_NUM_OVERFLOW, /** Seq number overflow */

> +} odp_ipsec_notif_type_t;

> +

> +typedef struct odp_ipsec_notif_info {

> +       odp_ipsec_notif_type_t notif_type;

> +       odp_ipsec_policy_t policy;

> +       odp_ipsec_session_t session;

> +}odp_ipsec_notif_info_t;

>


space after } (checkpatch)


> +

> +/**

> + * @brief This API gets notification queue for ODP IPSEC module.

> + *

> + * @param[out] queue - Handle to the IPSEC notification queue.

> + *

> + * @returns SUCCESS on success; FAILURE otherwise

> + *

> + */

> +int32_t odp_ipsec_get_notification_queue(odp_queue_t *queue);

> +

> +/**

> + * Return crypto notification handle that is associated with event

> + *

> + * Note: any invalid parameters will cause undefined behavior and may

> cause

> + * the application to abort or crash.

> + *

> + * @param ev An event of type ODP_EVENT_CRYPTO_NOTIF

> + *

> + * @return crypto completion handle

> + */

> +odp_crypto_notif_t odp_crypto_notif_from_event(odp_event_t ev);

> +

> +

> +/**

> + * Return notification info of this crypto notification event.

> + *

> + * @param[in] notif_ev An event of type ODP_EVENT_CRYPTO_NOTIF

> + * @param[out] notif_info structure populated with notification info

> + *

> + * @return success/failure

> + */

> +uint32_t odp_ipsec_notif_info_from_event(odp_crypto_notif_t notif_ev

> +               odp_ipsec_notif_info_t* notif_info);

> +

> +/**

> + * SPD Policy Statistics information structure

> + */

> +typedef struct odp_ipsec_spd_stats {

> +       uint64_t received_pkts;

> +       /** Received Outbound/Inbound packets */

> +       uint64_t processed_pkts;

> +       /** Processed Outbound/Inbound packets */

> +       uint64_t processed_bytes;

> +       /** Number of bytes processed on Inbound/Outbound policy */

> +

> +       /** Struct details

> +        */

> +       struct {

> +               uint32_t crypto_op_failed;

> +               /** Crypto operations failed */

> +       }protocol_violation_errors;

> +       /** Protocol violation errors */

> +

> +       /** Struct details

> +        */

> +       struct {

> +               uint32_t no_matching_dscp_range;

> +               /** Matching dscp range not found in the SPD policy */

> +

> +               uint32_t submit_to_sec_failed;

> +               /** Submission to SEC failed for crypto operations */

> +               uint32_t no_outb_sa;

> +               /** Outbound SA not found */

> +               uint32_t frag_failed;

> +               /** Fragmentation failed */

> +               uint32_t mem_alloc_failed;

> +               /** Memory allocation failed for SA/SPD/descriptor etc.*/

> +               uint32_t internal_error;

> +               /** All other errors locally encountered */

> +       }local_errors;

> +       /** Local/internal errors */

> +

>


No space here (checkpatch)


> +}odp_ipsec_spd_stats_t;

> +

> +/**

> + * @brief This API fetches global statistics.

> + *

> + * @param[out] stats  Pointer to statistics structure filled by this API.

> + *

> + * @returns 0 on Success or negative value on failure.

> + *

> + */

> +int32_t odp_ipsec_global_stats_get(odp_ipsec_spd_stats_t *stats);

>


No _get suffix on getters. So this should be odp_ipsec_global_stats()


> +

> +/**

> + * IPSec Module Capabilities

> + */

> +struct odp_ipsec_capabilities {

> +       /** This parameter indicates if IPSec-DP is capable of doing SPD

> +        * rule search for incoming or outgoing datagrams

> +        */

> +

> +       uint32_t sel_store_in_spd : 1,

> +

> +                /** Authentication Header processing */

> +                ah_protocol:1,

> +

> +                /** ESP Header processing */

> +                esp_protocol:1,

> +

> +                /** IPComp related processing */

> +                ipcomp_protocol:1,

> +

> +                /** IPSec Tunnel Mode processing */

> +                tunnel_mode:1,

> +

> +                /** IPSec Tunnel Mode processing */

> +                transport_mode:1,

> +

> +                /** This indicates if IPSec has capability to generate

> +                 * (for Outbound) and verify (for Inbound) extended

> sequence numbers.

> +                 */

> +                esn:1,

> +

> +                /** This option indicates whether IPSec can

> +                 * handle the necessary UDP Encapsulation required at

> +                 * IPSec level for traversing NAT boxes.

> +                 */

> +                udp_encap:1,

> +

> +                /** This option indicates whether IPSec can fragment

> packets

> +                 * before IPSec encryption, so that the resulting IPSec

> encrypted

> +                 * fragments do not exceed MTU

> +                 */

> +                redside_frag:1,

> +

> +

> +       /** Indicates the maximum number of IN and OUT SPD policies. */

> +       uint32_t            max_spd_policies;

> +

> +       /** Indicates the maximum number of IN and OUT IPSec SAs. */

> +       uint32_t             max_sas;

> +}odp_ipsec_capabilities_t;

>


space after } (checkpatch)

This should be odp_ipsec_capability_t for consistency with other capability
structs.


> +

> +/**

> + * @brief This API fetches IPSec module Capabilities

> + *

> + * @param[out] capa - capabilities structure filled by API.

> + *

> + * @returns SUCCESS on success; FAILURE otherwise

> + *

> + */

> +int32_t odp_ipsec_capabilities_get(odp_ipsec_capabilities_t *capa);

>


This should be named odp_ipsec_capability() for consistency with other
capability APIs.


> +

> +

> +#endif /* __IPSEC_API_H */

> +/**

> + * @}

> + */

> +

> +#ifdef __cplusplus

> +}

> +#endif

> +

> +#endif

> diff --git a/platform/linux-generic/include/odp/api/plat/event_types.h

> b/platform/linux-generic/include/odp/api/plat/event_types.h

> index 9ca0fb8..b083d3e 100644

> --- a/platform/linux-generic/include/odp/api/plat/event_types.h

> +++ b/platform/linux-generic/include/odp/api/plat/event_types.h

> @@ -38,6 +38,7 @@ typedef enum odp_event_type_t {

>         ODP_EVENT_PACKET       = 2,

>         ODP_EVENT_TIMEOUT      = 3,

>         ODP_EVENT_CRYPTO_COMPL = 4,

> +       ODP_EVENT_CRYPTO_notif = 5,

>


Typo, as Josep previously noted.


>  } odp_event_type_t;

>

>  /** Get printable format of odp_event_t */

> --

> 2.9.3

>

>
François Ozog Nov. 3, 2016, 1:25 p.m. UTC | #3
Hi,

Some hardware can accept clear IP packets, some require segmentation to be
done and IPSec headers prepended before sending the packets (unencrypted)
to HW.

I would have expected capabilities reflect that so that ODP knows what to
do: we don't want upper layers to be exposed to this HW specifics things.
The flow would be:

1) OFP/SISU send clear packet (say 1500 bytes) to ODP IPSec API
2) depending on capabilities
   a. ODP sends the packet to HW for encryption and send (including
fragmentation)
or
   b. ODP splits packet according to MTU, prepends IPSec headers, deal with
sequence numbers (optional), sends packets to HW for encryption and send

How to deal with anti-replay attacks and seq number handling?

How to control ICMP messages related to MTU so that upper TCP layers are
aware of the required actions when IPSec is handled in HW? ICMP proxying by
HW?


FF

On 26 October 2016 at 04:55, Bill Fischofer <bill.fischofer@linaro.org>
wrote:

> On Mon, Oct 24, 2016 at 12:04 PM, Nikhil Agarwal <

> nikhil.agarwal@linaro.org>

> wrote:

>

> > This RFC introduces IPSEC crypto offload APIs. These APIs can be used in

> > accelerator

> > pipeline model or for look aside IPSEC model.

> >

> > TODO items:

> > - statistics amd capability APIs

> > - Encrypt and send APIs

> >

> > Signed-off-by: Nikhil Agarwal <nikhil.agarwal@linaro.org>

> > ---

> >  include/odp/api/spec/crypto.h                      |  29 ++

> >  include/odp/api/spec/crypto_ipsec.h                | 449

> > +++++++++++++++++++++

> >  .../include/odp/api/plat/event_types.h             |   1 +

> >  3 files changed, 479 insertions(+)

> >  create mode 100644 include/odp/api/spec/crypto_ipsec.h

> >

> > diff --git a/include/odp/api/spec/crypto.h

> b/include/odp/api/spec/crypto.h

> > index dea1fe9..3a67d92 100644

> > --- a/include/odp/api/spec/crypto.h

> > +++ b/include/odp/api/spec/crypto.h

> > @@ -144,6 +144,27 @@ typedef union odp_crypto_auth_algos_t {

> >         uint32_t all_bits;

> >  } odp_crypto_auth_algos_t;

> >

> > +

> > +/**

> > + * Network security protocols in bit field structure

> > + */

> > +typedef union odp_crypto_protocol_t {

> > +       /** Network security protocols */

> > +       struct {

> > +               /** ESP Protocol */

> > +               uint32_t ipsec_esp    : 1;

> > +

> > +               /** AH protocol */

> > +               uint32_t ipsec_ah     : 1;

> > +

> > +       } bit;

> > +

> > +       /** All bits of the bit field structure

> > +         *

> > +         * This field can be used to set/clear all flags, or bitwise

> > +         * operations over the entire structure. */

> > +       uint32_t all_bits;

> > +} odp_crypto_protocol_t;

> >  /**

> >   * Crypto API key structure

> >   */

> > @@ -264,6 +285,8 @@ typedef enum {

> >         ODP_CRYPTO_SES_CREATE_ERR_INV_CIPHER,

> >         /** Creation failed, bad auth params */

> >         ODP_CRYPTO_SES_CREATE_ERR_INV_AUTH,

> > +       /** Creation failed, bad protocol params */

> > +       ODP_CRYPTO_SES_CREATE_ERR_INV_PROTO,

> >  } odp_crypto_ses_create_err_t;

> >

> >  /**

> > @@ -332,6 +355,12 @@ typedef struct odp_crypto_capability_t {

> >         /** Authentication algorithms implemented with HW offload */

> >         odp_crypto_auth_algos_t   hw_auths;

> >

> > +       /** Supported authentication algorithms */

> > +       odp_crypto_protocol_t   protocols;

> > +

> > +       /** Authentication algorithms implemented with HW offload */

> > +       odp_crypto_protocol_t   hw_protocols;

> > +

> >  } odp_crypto_capability_t;

> >

> >  /**

> > diff --git a/include/odp/api/spec/crypto_ipsec.h

> > b/include/odp/api/spec/crypto_ipsec.h

> > new file mode 100644

> > index 0000000..5916ea0

> > --- /dev/null

> > +++ b/include/odp/api/spec/crypto_ipsec.h

> > @@ -0,0 +1,449 @@

> > +/* Copyright (c) 2014, Linaro Limited

> > + * Copyright (c) 2015 - 2016 Freescale Semiconductor, Inc.

> >

>

> Linaro copyright should be 2016, not 2014.

> Freescale copyright should be 2016, not 2015. Should this also be NXP here?

>

>

> > + * All rights reserved.

> > + *

> > + * SPDX-License-Identifier:    BSD-3-Clause

> > + */

> > +

> > +/**

> > + * @file

> > + *

> > + * ODP crypto IPSec extension

> >

>

> We need to be consistent with how this acronym is written. The proper

> spelling/case is IPsec, per the normative reference RFC 4301 and addenda.

> No other case variants should be used in documentation. All caps IPSEC is

> fine in enums and #defines when used in code. All lower case ipsec is fine

> in api names.

>

>

> > + */

> > +

> > +#ifndef ODP_API_CRYPTO_IPSEC_H_

> > +#define ODP_API_CRYPTO_IPSEC_H_

> > +

> > +#ifdef __cplusplus

> > +extern "C" {

> > +#endif

> > +

> > +

> > +typedef enum odp_ipsec_mode {

> > +       ODP_IPSEC_MODE_TUNNEL,      /** IPSec tunnel mode */

> > +       ODP_IPSEC_MODE_TRANSPORT,   /** IPSec transport mode */

> > +} odp_ipsec_mode_t;

> > +

> > +typedef enum odp_ipsec_proto {

> > +       ODP_IPSEC_ESP,             /** ESP protocol */

> > +       ODP_IPSEC_AH,              /** AH protocol */

> > +} odp_ipsec_proto_t;

> > +

> > +typedef enum odp_ipsec_outhdr_type {

> > +       ODP_IPSEC_OUTHDR_IPV4,    /** Outer header is IPv4 */

> > +       ODP_IPSEC_OUTHDR_IPV6,    /** Outer header is IPv6 */

> > +} odp_ipsec_outhdr_type_t;

> > +

> > +/**

> > +  * ODP IPSEC flags bit feilds structure

> > +  */

> > +

> > +typedef struct odp_ipsec_session_flags {

> > +       uint32_t esn : 1;

> > +       /** When enabled, extended sequence numbers is used */

> > +       uint32_t nat_t : 1;

> > +       /** When enabled, this indicates that UDP

> > encapsulation/decapsulation

> > +         * for IPSEC packet has to be done so that IPSEC packet can

> > traverse

> > +         * through NAT boxes. UDP encapsulation/decapsulation is to be

> > applied

> > +         * for packets that get processed off this SA.

> > +         */

> > +       uint32_t copy_dscp : 1;

> > +       /** When enabled, Copy the IPv4 TOS or IPv6 Traffic Class byte

> from

> > +         * inner/outer IP header to the outer/inner IP header. If

> disabled

> > +         * values from configured Header will be used */

> > +       uint32_t copy_df : 1;

> > +       /** When enabled, copy the DF bit from the inner IP header to the

> > outer

> > +         * IP header. If disabled, values from configured Header will be

> > used */

> > +

> > +       uint32_t ip_dttl : 1;

> > +       /** When enabled,IPv4 ttl/IPv6 Hop Limit feild will be

> decremented

> > +         * in case of tunnel mode encap & decap */

> > +

> > +       uint32_t remove_outer_hdr : 1;

> > +       /** remove outer header - tunnel mode decap */

> > +

> > +       uint32_t verify_sa_selectors : 1;

> > +       /** This flag is only application to inbound sessions. When

> > enabled,

> > +         * this indicates that post decryption, selectors needs to be

> > verified

> > +         * for this session. */

> > +

> >

>

> No blank line here (checkpatch)

>

>

> > +} odp_ipsec_session_flags_t;

> > +

> > +typedef enum odp_ipsec_sa_lifetime_type {

> > +       ODP_IPSEC_SA_LIFETIME_IN_SEC, /** SA life time is in seconds */

> > +       ODP_IPSEC_SA_LIFETIME_IN_KB,  /** SA life time is in kilo bytes

> */

> > +       ODP_IPSEC_SA_LIFETIME_IN_PKT_CNT, /** SA life time is in packet

> > count */

> > +} odp_ipsec_sa_lifetime_type_t;

> >

>

> As noted during today's public call, we need to be able to specify a

> lifetime to be whichever comes first: a specified number of bytes used by

> this SA, or an elapsed number of seconds.

>

>

> > +

> > +typedef struct odp_ipsec_params {

> > +       odp_ipsec_mode_t ipsec_mode; /** Transport or Tunnel */

> > +       odp_ipsec_proto_t ipsec_proto; /** IPSEC protocol ESP/AH */

> > +       uint64_t seq;            /** Initial SEQ number */

> > +       uint32_t spi;            /** SPI value */

> > +       uint16_t ar_ws; /** Anti-replay window size. Value 0 indicates

> that

> > +                         Anti-replay window check is disabled for this

> SA

> > */

> > +       uint16_t out_hdr_size;   /** outer header size - tunnel mode */

> > +       uint8_t *out_hdr;        /** outer header - tunnel mode */

> > +       odp_ipsec_outhdr_type_t out_hdr_type; /** outer header type

> tunnel

> > mode*/

> > +       odp_ipsec_session_flags_t sa_flags; /** SA control flags */

> > +       odp_ipsec_sa_lifetime_type_t lifetime_type; /** lifetime type */

> > +       uint64_t soft_expiry_limit;

> > +       /** Soft expiry for this session, values may be in seconds,

> > Kilobytes or

> > +         * number of packets depending on feild

> > odp_ipsec_sa_lifetime_type_t */

> > +       uint64_t hard_expiry_limit;

> > +       /** Hard expiry for this session, values may be in seconds,

> > Kilobytes or

> > +         * number of packets depending on feild

> > odp_ipsec_sa_lifetime_type_t */

> >

>

> Need to clarify what soft and hard limits mean here. I'm assuming that when

> the soft limit is hit, a notification is sent so that rekeying processing

> can begin while the old keys continue to be used. When the hard limit is

> hit, the SA is invalidated so any further attempts to use it will fail.

>

>

> > +

> >

>

> No blank line here (checkpatch)

>

>

> > +} odp_ipsec_params_t;

> >

>

> Other param structs in ODP (odp_pool_param_t, odp_queue_param_t,

> odp_pktin_queue_param_t, etc. all use the singular param rather than

> params. We should follow this model here so this should be

> odp_ipsec_param_t. We should also probably change

> odp_crypto_session_params_t to odp_crypto_session_param_t and

> odp_crypto_op_params_t to odp_crypto_op_param_t as well for consistency as

> a separate API change patch for Tiger Moth.

>

> We also should have an odp_ipsec_param_init() API to initialize this to a

> default state for consistency with other param structs. And add

> corresponding init() APIs for odp_crypto_session_param_t and

> odp_crypto_op_param_t as well.

>

>

> > +

> > +/**

> > + * Configure crypto session for IPsec processing

> > + *

> > + * Configures a crypto session for IPSec protocol processing.

> > + * Packets submitted to an IPSec enabled session will have

> > + * relevant IPSec headers/trailers and tunnel headers

> > + * added/removed by the crypto implementation.

> > + * For example, the input packet for an IPSec ESP transport

> > + * enabled session should be the clear text packet with

> > + * no ESP headers/trailers prepared in advance for crypto operation.

> > + * The output packet will have ESP header, IV, trailer and the ESP ICV

> > + * added by crypto implementation.

> > + * Depending on the particular capabilities of an implementation and

> > + * the parameters enabled by application, the application may be

> > + * partially or completely offloaded from IPSec protocol processing.

> > + * For example, if an implementation does not support checksum

> > + * update for IP header after adding ESP header the application

> > + * should update after crypto IPSec operation.

> > + *

> > + * If an implementation does not support a particular set of

> > + * arguments it should return error.

> > + *

> > + * @param session          Session handle

> >

>

> Inconsistent. This is specified as ses_params in the API below. Pick one.

> Larger question is should this be specified as a field within the

> odp_ipsec_param_t struct? What's the use case for separating these two so

> that the same odp_ipsec_param_t can be used with different

> odp_crypto_session_param_t's?

>

>

> > + * @param ipsec_params     IPSec parameters. Parameters which are not

> > + *                         relevant for selected protocol & mode are

> > ignored -

> > + *                         e.g. outer_hdr/size set for ESP transport

> mode.

> >

>

> You're missing @param info for the other two parameters (session_out,

> status)

>

>

> > + * @retval 0 on success

> > + * @retval <0 on failure

> > + */

> > +int odp_crypto_ipsec_session_create(odp_crypto_session_params_t

> > *ses_params,

> > +                                   odp_ipsec_params_t *ipsec_params,

>

> +                                   odp_crypto_session_t *session_out,

> >

>

> Should this be an overload of the existing odp_crypto_session_t type?

> Should this be a new odp_ipsec_session_t or odp_ipsec_session_t type?

>

>

> > +                                   odp_crypto_ses_create_err_t *status);

> >

>

> again, should this be an overload or a new type

> (odp_ipsec_ses_create_err_t)?

>

>

> > +

> > +

> > +/**

> > + * SPD Policy/SA direction information

> > + */

> > +typedef enum odp_ipsec_direction {

> > +       ODP_IPSEC_INBOUND,      /** Inbound Direction */

> > +       ODP_IPSEC_OUTBOUND      /** Outbound Direction */

> > +}odp_ipsec_direction_t;

> >

>

> space after } (checkpatch)

>

>

> > +

> > +/**

> > + * SPD Policy Action information

> > + */

> > +typedef enum odp_ipsec_policy_rule_action {

> > +       ODP_IPSEC_POLICY_ACTION_IPSEC, /** Apply IPSec processing on

> > Packet*/

> > +       ODP_IPSEC_POLICY_ACTION_DISCARD, /** Discard or Drop the packet

> */

> > +       ODP_IPSEC_POLICY_ACTION_BYPASS, /** Bypass/Allow to pass the

> > packet */

> > +}odp_ipsec_policy_rule_action_t;

> >

>

> space after } (checkpatch)

>

>

> > +

> > +/**

> > + * SPD Policy Position information

> > + */

> > +typedef enum odp_ipsec_policy_rule_position{

> >

>

> space before { (checkpatch)

>

>

> > +       ODP_IPSEC_POLICY_POSITION_BEGIN, /** Add at the beginning of the

> > list */

> > +       ODP_IPSEC_POLICY_POSITION_BEFORE, /** Add before the mentioned

> > Policy */

> > +       ODP_IPSEC_POLICY_POSITION_AFTER, /** Add after the mentioned

> > Policy */

> > +       ODP_IPSEC_POLICY_POSITION_END, /** Add at the end of the list */

> > +} odp_ipsec_policy_rule_position_t;

> > +

> > +

> > +/**

> > + * DSCP Range information

> > + */

> > +typedef struct odp_ipsec_policy_rule_dscprange {

> > +       uint8_t start;  /** Start value in Range */

> > +       uint8_t end;    /** End value  in Range */

> > +}odp_ipsec_policy_rule_dscprange_t;

> >

>

> space after } (checkpatch)

>

>

> > +

> > +/**

> > + * Fragmentation Before Encapsulation (Redside Fragmentation)

> > + */

> > +typedef enum odp_ipsec_policy_redside_fragmentation {

> > +       ODP_IPSEC_POLICY_REDSIDE_FRAGMENTATION_DISABLE = 0,

> > +       /** Disable Redside fragmentation in IPSec Policy */

> > +       ODP_IPSEC_POLICY_REDSIDE_FRAGMENTATION_ENABLE

> > +               /** Enable Redside fragmentation in IPSec Policy */

> > +}odp_ipsec_policy_redside_fragmentation_t;

> >

>

> space after } (checkpatch)

>

>

> > +

> > +/**

> > + * Input parameters to SPD Policy addition

> > + */

> > +struct odp_ipsec_spd_params{

>

>

> space before { (checkpatch)

> Why is this not a typedef? Should be for type odp_ipsec_spd_param_t (no

> plural). Also means we need an odp_ipsec_spd_param_init() API for

> completeness.

>

>

> > +       uint32_t tunnel_id;

> > +       /** Tunnel ID */

> > +       odp_ipsec_direction_t dir;

> > +       /** Direction: Inbound or Outbound */

> > +       odp_ipsec_policy_rule_action_t action;

> > +       /** SPD Policy Action */

> > +       odp_ipsec_policy_rule_position_t position;

> > +       /** Position of this policy in policy table */

> > +       odp_ipsec_policy_t relative_policy;

> >

>

> odp_ipsec_policy_t does not appear to be defined here. It's also referenced

> in several APIs below.

>

>

> > +       /** relative policy for the position in case of before/after */

> > +       uint32_t n_dscp_ranges;

> > +       /** Number of DSCP Ranges */

> > +       struct odp_ipsec_policy_rule_dscprange *dscp_ranges;

> > +       /** Array of DSCP Ranges */

> > +       enum odp_ipsec_policy_redside_fragmentation redside;

> > +       /** Fragmentation before Encapsulation option: TRUE/FALSE */

> > +       uint32_t n_selectors;

> > +       /** Number of selectors */

> > +       const odp_pmr_param_t *selectors;

> > +       /** Array of Selectors */

> > +};

> > +

> > +/**

> > + * Output parameters to SPD Policy addition

> > + */

> > +typedef struct odp_ipsec_spd_add_err{

> >

>

> space before { (checkpatch)

>

>

> > +       int32_t result;

> > +       /** 0:Success; Non Zero value: Error code indicating failure */

> > +}odp_ipsec_pol_add_err_t;

> >

>

> space after } (checkpatch)

>

> Does this need to be a struct? Do we expect to expand this? Seems

> cumbersome if the only output is a simple return code.

>

>

> > +

> > +/**

> > + * @brief This API is used to add Inbound/Outbound SPD policy to SPD

> > policy

> > + * database.  This database is maintained per Name Space and Tunnel

> > instance.

> > + * This function first validates the incoming parameters

> > + * and if all validations succeed, new SPD policy is added to the

> > database.

> > + *

> > + * @param[in] params   Pointer to input param structure which contains

> > + *                     spd policy information.

> > + * @param[out] policy  Handle to the IPSEC policy.

> > + * @param[out] resp    Failure code if unsuccessful.

> > + *

> > + * @returns 0 on Success or negative value on failure.

> > + *

> > + */

> > +int32_t odp_ipsec_spd_add(

> > +               const struct odp_ipsec_spd_params *params,

> >

>

> should be const odp_ipsec_spd_param_t *params,

>

>

> > +               odp_ipsec_policy_t *policy,

> > +               odp_ipsec_pol_add_err_t *resp);

> > +

> > +/**

> > + * @brief This API is used to delete Inbound/Outbound SPD policy from

> SPD

> > policy

> > + * database.

> > + *

> > + * @param[in] policy   Handle to the IPSEC policy.

> > + *

> > + * @returns 0 on Success or negative value on failure.

> > + *

> > + */

> > +int32_t odp_ipsec_spd_del(odp_ipsec_policy_t policy);

> > +

> > +/**

> > + * @brief This API is used to flush/delete all Inbound and Outbound SPD

> > + * policies.

> > + *

> > + * @returns 0 on Success or negative value on failure.

> > + *

> > + */

> > +int32_t odp_ipsec_spd_flush();

> >

>

> Syntax: must be odp_ipsec_spd_flush(void);

>

>

> > +

> > +/**

> > + * @brief This API maps an IPSEC policy to an IPSEC crypto session.

> > + *

> > + * @param[in] policy - Handle to the IPSEC policy.

> > + * @param[in] session - Handle to the IPSEC session(SA).

> > + *

> > + * @returns SUCCESS on success; FAILURE otherwise

> > + *

> > + */

> > +int32_t odp_ipsec_map_pol_session(odp_ipsec_policy_t policy

> >

>

> pol is an awkward abbreviation. odp_ipsec_map_policy_session() would seem

> to be preferable here.

>

>

> > +               odp_crypto_session_t session);

> >

>

> See earlier comments regarding overload of odp_crypto_session_t type.

>

> +

> > +/**

> > + * @brief This API unmaps an IPSEC policy to an IPSEC crypto session.

> >

>

> ...from an IPsec crypto session

>

>

> > + *

> > + * @param[in] policy - Handle to the IPSEC policy.

> > + * @param[in] session - Handle to the IPSEC session(SA).

> > + *

> > + * @returns SUCCESS on success; FAILURE otherwise

> > + *

> > + */

> > +int32_t odp_ipsec_unmap_pol_session(odp_ipsec_policy_t policy

> >

>

> Again, odp_ipsec_unmap_policy_session()

>

>

> > +               odp_crypto_session_t session);

> >

>

> Same question on overload of this type.

>

>

> > +

> > +/**

> > +  * ODP ipsec notification event type

> > +  */

> > +

> > +typedef enum odp_ipsec_notif_type {

> > +       ODP_IPSEC_NO_OUB_SA, /** IPSEC policy matched but Outbound SA not

> > found */

> > +       ODP_IPSEC_NO_INB_SA, /** IPSEC policy matched but inbound SA not

> > found */

> > +       ODP_IPSEC_SA_SOFT_EXPIRY, /** SA soft expiry limit reached */

> > +       ODP_IPSEC_SA_HARD_EXPIRY, /** SA hard expiry limit reached */

> > +       ODP_IPSEC_SA_SEQ_NUM_OVERFLOW, /** Seq number overflow */

> > +} odp_ipsec_notif_type_t;

> > +

> > +typedef struct odp_ipsec_notif_info {

> > +       odp_ipsec_notif_type_t notif_type;

> > +       odp_ipsec_policy_t policy;

> > +       odp_ipsec_session_t session;

> > +}odp_ipsec_notif_info_t;

> >

>

> space after } (checkpatch)

>

>

> > +

> > +/**

> > + * @brief This API gets notification queue for ODP IPSEC module.

> > + *

> > + * @param[out] queue - Handle to the IPSEC notification queue.

> > + *

> > + * @returns SUCCESS on success; FAILURE otherwise

> > + *

> > + */

> > +int32_t odp_ipsec_get_notification_queue(odp_queue_t *queue);

> > +

> > +/**

> > + * Return crypto notification handle that is associated with event

> > + *

> > + * Note: any invalid parameters will cause undefined behavior and may

> > cause

> > + * the application to abort or crash.

> > + *

> > + * @param ev An event of type ODP_EVENT_CRYPTO_NOTIF

> > + *

> > + * @return crypto completion handle

> > + */

> > +odp_crypto_notif_t odp_crypto_notif_from_event(odp_event_t ev);

> > +

> > +

> > +/**

> > + * Return notification info of this crypto notification event.

> > + *

> > + * @param[in] notif_ev An event of type ODP_EVENT_CRYPTO_NOTIF

> > + * @param[out] notif_info structure populated with notification info

> > + *

> > + * @return success/failure

> > + */

> > +uint32_t odp_ipsec_notif_info_from_event(odp_crypto_notif_t notif_ev

> > +               odp_ipsec_notif_info_t* notif_info);

> > +

> > +/**

> > + * SPD Policy Statistics information structure

> > + */

> > +typedef struct odp_ipsec_spd_stats {

> > +       uint64_t received_pkts;

> > +       /** Received Outbound/Inbound packets */

> > +       uint64_t processed_pkts;

> > +       /** Processed Outbound/Inbound packets */

> > +       uint64_t processed_bytes;

> > +       /** Number of bytes processed on Inbound/Outbound policy */

> > +

> > +       /** Struct details

> > +        */

> > +       struct {

> > +               uint32_t crypto_op_failed;

> > +               /** Crypto operations failed */

> > +       }protocol_violation_errors;

> > +       /** Protocol violation errors */

> > +

> > +       /** Struct details

> > +        */

> > +       struct {

> > +               uint32_t no_matching_dscp_range;

> > +               /** Matching dscp range not found in the SPD policy */

> > +

> > +               uint32_t submit_to_sec_failed;

> > +               /** Submission to SEC failed for crypto operations */

> > +               uint32_t no_outb_sa;

> > +               /** Outbound SA not found */

> > +               uint32_t frag_failed;

> > +               /** Fragmentation failed */

> > +               uint32_t mem_alloc_failed;

> > +               /** Memory allocation failed for SA/SPD/descriptor etc.*/

> > +               uint32_t internal_error;

> > +               /** All other errors locally encountered */

> > +       }local_errors;

> > +       /** Local/internal errors */

> > +

> >

>

> No space here (checkpatch)

>

>

> > +}odp_ipsec_spd_stats_t;

> > +

> > +/**

> > + * @brief This API fetches global statistics.

> > + *

> > + * @param[out] stats  Pointer to statistics structure filled by this

> API.

> > + *

> > + * @returns 0 on Success or negative value on failure.

> > + *

> > + */

> > +int32_t odp_ipsec_global_stats_get(odp_ipsec_spd_stats_t *stats);

> >

>

> No _get suffix on getters. So this should be odp_ipsec_global_stats()

>

>

> > +

> > +/**

> > + * IPSec Module Capabilities

> > + */

> > +struct odp_ipsec_capabilities {

> > +       /** This parameter indicates if IPSec-DP is capable of doing SPD

> > +        * rule search for incoming or outgoing datagrams

> > +        */

> > +

> > +       uint32_t sel_store_in_spd : 1,

> > +

> > +                /** Authentication Header processing */

> > +                ah_protocol:1,

> > +

> > +                /** ESP Header processing */

> > +                esp_protocol:1,

> > +

> > +                /** IPComp related processing */

> > +                ipcomp_protocol:1,

> > +

> > +                /** IPSec Tunnel Mode processing */

> > +                tunnel_mode:1,

> > +

> > +                /** IPSec Tunnel Mode processing */

> > +                transport_mode:1,

> > +

> > +                /** This indicates if IPSec has capability to generate

> > +                 * (for Outbound) and verify (for Inbound) extended

> > sequence numbers.

> > +                 */

> > +                esn:1,

> > +

> > +                /** This option indicates whether IPSec can

> > +                 * handle the necessary UDP Encapsulation required at

> > +                 * IPSec level for traversing NAT boxes.

> > +                 */

> > +                udp_encap:1,

> > +

> > +                /** This option indicates whether IPSec can fragment

> > packets

> > +                 * before IPSec encryption, so that the resulting IPSec

> > encrypted

> > +                 * fragments do not exceed MTU

> > +                 */

> > +                redside_frag:1,

> > +

> > +

> > +       /** Indicates the maximum number of IN and OUT SPD policies. */

> > +       uint32_t            max_spd_policies;

> > +

> > +       /** Indicates the maximum number of IN and OUT IPSec SAs. */

> > +       uint32_t             max_sas;

> > +}odp_ipsec_capabilities_t;

> >

>

> space after } (checkpatch)

>

> This should be odp_ipsec_capability_t for consistency with other capability

> structs.

>

>

> > +

> > +/**

> > + * @brief This API fetches IPSec module Capabilities

> > + *

> > + * @param[out] capa - capabilities structure filled by API.

> > + *

> > + * @returns SUCCESS on success; FAILURE otherwise

> > + *

> > + */

> > +int32_t odp_ipsec_capabilities_get(odp_ipsec_capabilities_t *capa);

> >

>

> This should be named odp_ipsec_capability() for consistency with other

> capability APIs.

>

>

> > +

> > +

> > +#endif /* __IPSEC_API_H */

> > +/**

> > + * @}

> > + */

> > +

> > +#ifdef __cplusplus

> > +}

> > +#endif

> > +

> > +#endif

> > diff --git a/platform/linux-generic/include/odp/api/plat/event_types.h

> > b/platform/linux-generic/include/odp/api/plat/event_types.h

> > index 9ca0fb8..b083d3e 100644

> > --- a/platform/linux-generic/include/odp/api/plat/event_types.h

> > +++ b/platform/linux-generic/include/odp/api/plat/event_types.h

> > @@ -38,6 +38,7 @@ typedef enum odp_event_type_t {

> >         ODP_EVENT_PACKET       = 2,

> >         ODP_EVENT_TIMEOUT      = 3,

> >         ODP_EVENT_CRYPTO_COMPL = 4,

> > +       ODP_EVENT_CRYPTO_notif = 5,

> >

>

> Typo, as Josep previously noted.

>

>

> >  } odp_event_type_t;

> >

> >  /** Get printable format of odp_event_t */

> > --

> > 2.9.3

> >

> >

>




-- 
[image: Linaro] <http://www.linaro.org/>
François-Frédéric Ozog | *Director Linaro Networking Group*
T: +33.67221.6485
francois.ozog@linaro.org | Skype: ffozog
Nikhil Agarwal Nov. 4, 2016, 6:12 a.m. UTC | #4
On 3 November 2016 at 18:55, Francois Ozog <francois.ozog@linaro.org> wrote:

> Hi,

>

> Some hardware can accept clear IP packets, some require segmentation to be

> done and IPSec headers prepended before sending the packets (unencrypted)

> to HW.

>

> I would have expected capabilities reflect that so that ODP knows what to

> do: we don't want upper layers to be exposed to this HW specifics things.

> The flow would be:

>

> 1) OFP/SISU send clear packet (say 1500 bytes) to ODP IPSec API

> 2) depending on capabilities

>    a. ODP sends the packet to HW for encryption and send (including

> fragmentation)

> or

>    b. ODP splits packet according to MTU, prepends IPSec headers, deal

> with sequence numbers (optional), sends packets to HW for encryption and

> send

>

[Nikhil] ODP API will behave in similar way. Policy parameter
ODP_IPSEC_POLICY_REDSIDE_FRAGMENTATION_ENABLE will control whether to
fragment plain packet and then encrypt 2 packets or encrypt first and then
fragment the ciphered packet. This capability of RED(random early
detection) side fragmentation will be a capability that implementation may
support and will inform the application through capability APIs.

>

> How to deal with anti-replay attacks and seq number handling?

>

Session param uint16_t ar_ws controls anti replay enable/disable and anti
replay window configuration.
esn bit in session flags indicates whether to use extended seq number or
not. User can also configure initial seq number for session using session
params.
ODP_IPSEC_SA_SEQ_NUM_OVERFLOW type of notification from ODP will let the
application know that seq num for a session has overflown and needs proper
action from user.


>

> How to control ICMP messages related to MTU so that upper TCP layers are

> aware of the required actions when IPSec is handled in HW? ICMP proxying by

> HW?

>

These features are yet not include in the RFC.

>

>

> FF

>

> On 26 October 2016 at 04:55, Bill Fischofer <bill.fischofer@linaro.org>

> wrote:

>

>> On Mon, Oct 24, 2016 at 12:04 PM, Nikhil Agarwal <

>> nikhil.agarwal@linaro.org>

>> wrote:

>>

>> > This RFC introduces IPSEC crypto offload APIs. These APIs can be used in

>> > accelerator

>> > pipeline model or for look aside IPSEC model.

>> >

>> > TODO items:

>> > - statistics amd capability APIs

>> > - Encrypt and send APIs

>> >

>> > Signed-off-by: Nikhil Agarwal <nikhil.agarwal@linaro.org>

>> > ---

>> >  include/odp/api/spec/crypto.h                      |  29 ++

>> >  include/odp/api/spec/crypto_ipsec.h                | 449

>> > +++++++++++++++++++++

>> >  .../include/odp/api/plat/event_types.h             |   1 +

>> >  3 files changed, 479 insertions(+)

>> >  create mode 100644 include/odp/api/spec/crypto_ipsec.h

>> >

>> > diff --git a/include/odp/api/spec/crypto.h

>> b/include/odp/api/spec/crypto.h

>> > index dea1fe9..3a67d92 100644

>> > --- a/include/odp/api/spec/crypto.h

>> > +++ b/include/odp/api/spec/crypto.h

>> > @@ -144,6 +144,27 @@ typedef union odp_crypto_auth_algos_t {

>> >         uint32_t all_bits;

>> >  } odp_crypto_auth_algos_t;

>> >

>> > +

>> > +/**

>> > + * Network security protocols in bit field structure

>> > + */

>> > +typedef union odp_crypto_protocol_t {

>> > +       /** Network security protocols */

>> > +       struct {

>> > +               /** ESP Protocol */

>> > +               uint32_t ipsec_esp    : 1;

>> > +

>> > +               /** AH protocol */

>> > +               uint32_t ipsec_ah     : 1;

>> > +

>> > +       } bit;

>> > +

>> > +       /** All bits of the bit field structure

>> > +         *

>> > +         * This field can be used to set/clear all flags, or bitwise

>> > +         * operations over the entire structure. */

>> > +       uint32_t all_bits;

>> > +} odp_crypto_protocol_t;

>> >  /**

>> >   * Crypto API key structure

>> >   */

>> > @@ -264,6 +285,8 @@ typedef enum {

>> >         ODP_CRYPTO_SES_CREATE_ERR_INV_CIPHER,

>> >         /** Creation failed, bad auth params */

>> >         ODP_CRYPTO_SES_CREATE_ERR_INV_AUTH,

>> > +       /** Creation failed, bad protocol params */

>> > +       ODP_CRYPTO_SES_CREATE_ERR_INV_PROTO,

>> >  } odp_crypto_ses_create_err_t;

>> >

>> >  /**

>> > @@ -332,6 +355,12 @@ typedef struct odp_crypto_capability_t {

>> >         /** Authentication algorithms implemented with HW offload */

>> >         odp_crypto_auth_algos_t   hw_auths;

>> >

>> > +       /** Supported authentication algorithms */

>> > +       odp_crypto_protocol_t   protocols;

>> > +

>> > +       /** Authentication algorithms implemented with HW offload */

>> > +       odp_crypto_protocol_t   hw_protocols;

>> > +

>> >  } odp_crypto_capability_t;

>> >

>> >  /**

>> > diff --git a/include/odp/api/spec/crypto_ipsec.h

>> > b/include/odp/api/spec/crypto_ipsec.h

>> > new file mode 100644

>> > index 0000000..5916ea0

>> > --- /dev/null

>> > +++ b/include/odp/api/spec/crypto_ipsec.h

>> > @@ -0,0 +1,449 @@

>> > +/* Copyright (c) 2014, Linaro Limited

>> > + * Copyright (c) 2015 - 2016 Freescale Semiconductor, Inc.

>> >

>>

>> Linaro copyright should be 2016, not 2014.

>> Freescale copyright should be 2016, not 2015. Should this also be NXP

>> here?

>>

>>

>> > + * All rights reserved.

>> > + *

>> > + * SPDX-License-Identifier:    BSD-3-Clause

>> > + */

>> > +

>> > +/**

>> > + * @file

>> > + *

>> > + * ODP crypto IPSec extension

>> >

>>

>> We need to be consistent with how this acronym is written. The proper

>> spelling/case is IPsec, per the normative reference RFC 4301 and addenda.

>> No other case variants should be used in documentation. All caps IPSEC is

>> fine in enums and #defines when used in code. All lower case ipsec is fine

>> in api names.

>>

>>

>> > + */

>> > +

>> > +#ifndef ODP_API_CRYPTO_IPSEC_H_

>> > +#define ODP_API_CRYPTO_IPSEC_H_

>> > +

>> > +#ifdef __cplusplus

>> > +extern "C" {

>> > +#endif

>> > +

>> > +

>> > +typedef enum odp_ipsec_mode {

>> > +       ODP_IPSEC_MODE_TUNNEL,      /** IPSec tunnel mode */

>> > +       ODP_IPSEC_MODE_TRANSPORT,   /** IPSec transport mode */

>> > +} odp_ipsec_mode_t;

>> > +

>> > +typedef enum odp_ipsec_proto {

>> > +       ODP_IPSEC_ESP,             /** ESP protocol */

>> > +       ODP_IPSEC_AH,              /** AH protocol */

>> > +} odp_ipsec_proto_t;

>> > +

>> > +typedef enum odp_ipsec_outhdr_type {

>> > +       ODP_IPSEC_OUTHDR_IPV4,    /** Outer header is IPv4 */

>> > +       ODP_IPSEC_OUTHDR_IPV6,    /** Outer header is IPv6 */

>> > +} odp_ipsec_outhdr_type_t;

>> > +

>> > +/**

>> > +  * ODP IPSEC flags bit feilds structure

>> > +  */

>> > +

>> > +typedef struct odp_ipsec_session_flags {

>> > +       uint32_t esn : 1;

>> > +       /** When enabled, extended sequence numbers is used */

>> > +       uint32_t nat_t : 1;

>> > +       /** When enabled, this indicates that UDP

>> > encapsulation/decapsulation

>> > +         * for IPSEC packet has to be done so that IPSEC packet can

>> > traverse

>> > +         * through NAT boxes. UDP encapsulation/decapsulation is to be

>> > applied

>> > +         * for packets that get processed off this SA.

>> > +         */

>> > +       uint32_t copy_dscp : 1;

>> > +       /** When enabled, Copy the IPv4 TOS or IPv6 Traffic Class byte

>> from

>> > +         * inner/outer IP header to the outer/inner IP header. If

>> disabled

>> > +         * values from configured Header will be used */

>> > +       uint32_t copy_df : 1;

>> > +       /** When enabled, copy the DF bit from the inner IP header to

>> the

>> > outer

>> > +         * IP header. If disabled, values from configured Header will

>> be

>> > used */

>> > +

>> > +       uint32_t ip_dttl : 1;

>> > +       /** When enabled,IPv4 ttl/IPv6 Hop Limit feild will be

>> decremented

>> > +         * in case of tunnel mode encap & decap */

>> > +

>> > +       uint32_t remove_outer_hdr : 1;

>> > +       /** remove outer header - tunnel mode decap */

>> > +

>> > +       uint32_t verify_sa_selectors : 1;

>> > +       /** This flag is only application to inbound sessions. When

>> > enabled,

>> > +         * this indicates that post decryption, selectors needs to be

>> > verified

>> > +         * for this session. */

>> > +

>> >

>>

>> No blank line here (checkpatch)

>>

>>

>> > +} odp_ipsec_session_flags_t;

>> > +

>> > +typedef enum odp_ipsec_sa_lifetime_type {

>> > +       ODP_IPSEC_SA_LIFETIME_IN_SEC, /** SA life time is in seconds */

>> > +       ODP_IPSEC_SA_LIFETIME_IN_KB,  /** SA life time is in kilo bytes

>> */

>> > +       ODP_IPSEC_SA_LIFETIME_IN_PKT_CNT, /** SA life time is in packet

>> > count */

>> > +} odp_ipsec_sa_lifetime_type_t;

>> >

>>

>> As noted during today's public call, we need to be able to specify a

>> lifetime to be whichever comes first: a specified number of bytes used by

>> this SA, or an elapsed number of seconds.

>>

>>

>> > +

>> > +typedef struct odp_ipsec_params {

>> > +       odp_ipsec_mode_t ipsec_mode; /** Transport or Tunnel */

>> > +       odp_ipsec_proto_t ipsec_proto; /** IPSEC protocol ESP/AH */

>> > +       uint64_t seq;            /** Initial SEQ number */

>> > +       uint32_t spi;            /** SPI value */

>> > +       uint16_t ar_ws; /** Anti-replay window size. Value 0 indicates

>> that

>> > +                         Anti-replay window check is disabled for this

>> SA

>> > */

>> > +       uint16_t out_hdr_size;   /** outer header size - tunnel mode */

>> > +       uint8_t *out_hdr;        /** outer header - tunnel mode */

>> > +       odp_ipsec_outhdr_type_t out_hdr_type; /** outer header type

>> tunnel

>> > mode*/

>> > +       odp_ipsec_session_flags_t sa_flags; /** SA control flags */

>> > +       odp_ipsec_sa_lifetime_type_t lifetime_type; /** lifetime type */

>> > +       uint64_t soft_expiry_limit;

>> > +       /** Soft expiry for this session, values may be in seconds,

>> > Kilobytes or

>> > +         * number of packets depending on feild

>> > odp_ipsec_sa_lifetime_type_t */

>> > +       uint64_t hard_expiry_limit;

>> > +       /** Hard expiry for this session, values may be in seconds,

>> > Kilobytes or

>> > +         * number of packets depending on feild

>> > odp_ipsec_sa_lifetime_type_t */

>> >

>>

>> Need to clarify what soft and hard limits mean here. I'm assuming that

>> when

>> the soft limit is hit, a notification is sent so that rekeying processing

>> can begin while the old keys continue to be used. When the hard limit is

>> hit, the SA is invalidated so any further attempts to use it will fail.

>>

>>

>> > +

>> >

>>

>> No blank line here (checkpatch)

>>

>>

>> > +} odp_ipsec_params_t;

>> >

>>

>> Other param structs in ODP (odp_pool_param_t, odp_queue_param_t,

>> odp_pktin_queue_param_t, etc. all use the singular param rather than

>> params. We should follow this model here so this should be

>> odp_ipsec_param_t. We should also probably change

>> odp_crypto_session_params_t to odp_crypto_session_param_t and

>> odp_crypto_op_params_t to odp_crypto_op_param_t as well for consistency as

>> a separate API change patch for Tiger Moth.

>>

>> We also should have an odp_ipsec_param_init() API to initialize this to a

>> default state for consistency with other param structs. And add

>> corresponding init() APIs for odp_crypto_session_param_t and

>> odp_crypto_op_param_t as well.

>>

>>

>> > +

>> > +/**

>> > + * Configure crypto session for IPsec processing

>> > + *

>> > + * Configures a crypto session for IPSec protocol processing.

>> > + * Packets submitted to an IPSec enabled session will have

>> > + * relevant IPSec headers/trailers and tunnel headers

>> > + * added/removed by the crypto implementation.

>> > + * For example, the input packet for an IPSec ESP transport

>> > + * enabled session should be the clear text packet with

>> > + * no ESP headers/trailers prepared in advance for crypto operation.

>> > + * The output packet will have ESP header, IV, trailer and the ESP ICV

>> > + * added by crypto implementation.

>> > + * Depending on the particular capabilities of an implementation and

>> > + * the parameters enabled by application, the application may be

>> > + * partially or completely offloaded from IPSec protocol processing.

>> > + * For example, if an implementation does not support checksum

>> > + * update for IP header after adding ESP header the application

>> > + * should update after crypto IPSec operation.

>> > + *

>> > + * If an implementation does not support a particular set of

>> > + * arguments it should return error.

>> > + *

>> > + * @param session          Session handle

>> >

>>

>> Inconsistent. This is specified as ses_params in the API below. Pick one.

>> Larger question is should this be specified as a field within the

>> odp_ipsec_param_t struct? What's the use case for separating these two so

>> that the same odp_ipsec_param_t can be used with different

>> odp_crypto_session_param_t's?

>>

>>

>> > + * @param ipsec_params     IPSec parameters. Parameters which are not

>> > + *                         relevant for selected protocol & mode are

>> > ignored -

>> > + *                         e.g. outer_hdr/size set for ESP transport

>> mode.

>> >

>>

>> You're missing @param info for the other two parameters (session_out,

>> status)

>>

>>

>> > + * @retval 0 on success

>> > + * @retval <0 on failure

>> > + */

>> > +int odp_crypto_ipsec_session_create(odp_crypto_session_params_t

>> > *ses_params,

>> > +                                   odp_ipsec_params_t *ipsec_params,

>>

>> +                                   odp_crypto_session_t *session_out,

>> >

>>

>> Should this be an overload of the existing odp_crypto_session_t type?

>> Should this be a new odp_ipsec_session_t or odp_ipsec_session_t type?

>>

>>

>> > +                                   odp_crypto_ses_create_err_t

>> *status);

>> >

>>

>> again, should this be an overload or a new type

>> (odp_ipsec_ses_create_err_t)?

>>

>>

>> > +

>> > +

>> > +/**

>> > + * SPD Policy/SA direction information

>> > + */

>> > +typedef enum odp_ipsec_direction {

>> > +       ODP_IPSEC_INBOUND,      /** Inbound Direction */

>> > +       ODP_IPSEC_OUTBOUND      /** Outbound Direction */

>> > +}odp_ipsec_direction_t;

>> >

>>

>> space after } (checkpatch)

>>

>>

>> > +

>> > +/**

>> > + * SPD Policy Action information

>> > + */

>> > +typedef enum odp_ipsec_policy_rule_action {

>> > +       ODP_IPSEC_POLICY_ACTION_IPSEC, /** Apply IPSec processing on

>> > Packet*/

>> > +       ODP_IPSEC_POLICY_ACTION_DISCARD, /** Discard or Drop the

>> packet */

>> > +       ODP_IPSEC_POLICY_ACTION_BYPASS, /** Bypass/Allow to pass the

>> > packet */

>> > +}odp_ipsec_policy_rule_action_t;

>> >

>>

>> space after } (checkpatch)

>>

>>

>> > +

>> > +/**

>> > + * SPD Policy Position information

>> > + */

>> > +typedef enum odp_ipsec_policy_rule_position{

>> >

>>

>> space before { (checkpatch)

>>

>>

>> > +       ODP_IPSEC_POLICY_POSITION_BEGIN, /** Add at the beginning of

>> the

>> > list */

>> > +       ODP_IPSEC_POLICY_POSITION_BEFORE, /** Add before the mentioned

>> > Policy */

>> > +       ODP_IPSEC_POLICY_POSITION_AFTER, /** Add after the mentioned

>> > Policy */

>> > +       ODP_IPSEC_POLICY_POSITION_END, /** Add at the end of the list

>> */

>> > +} odp_ipsec_policy_rule_position_t;

>> > +

>> > +

>> > +/**

>> > + * DSCP Range information

>> > + */

>> > +typedef struct odp_ipsec_policy_rule_dscprange {

>> > +       uint8_t start;  /** Start value in Range */

>> > +       uint8_t end;    /** End value  in Range */

>> > +}odp_ipsec_policy_rule_dscprange_t;

>> >

>>

>> space after } (checkpatch)

>>

>>

>> > +

>> > +/**

>> > + * Fragmentation Before Encapsulation (Redside Fragmentation)

>> > + */

>> > +typedef enum odp_ipsec_policy_redside_fragmentation {

>> > +       ODP_IPSEC_POLICY_REDSIDE_FRAGMENTATION_DISABLE = 0,

>> > +       /** Disable Redside fragmentation in IPSec Policy */

>> > +       ODP_IPSEC_POLICY_REDSIDE_FRAGMENTATION_ENABLE

>> > +               /** Enable Redside fragmentation in IPSec Policy */

>> > +}odp_ipsec_policy_redside_fragmentation_t;

>> >

>>

>> space after } (checkpatch)

>>

>>

>> > +

>> > +/**

>> > + * Input parameters to SPD Policy addition

>> > + */

>> > +struct odp_ipsec_spd_params{

>>

>>

>> space before { (checkpatch)

>> Why is this not a typedef? Should be for type odp_ipsec_spd_param_t (no

>> plural). Also means we need an odp_ipsec_spd_param_init() API for

>> completeness.

>>

>>

>> > +       uint32_t tunnel_id;

>> > +       /** Tunnel ID */

>> > +       odp_ipsec_direction_t dir;

>> > +       /** Direction: Inbound or Outbound */

>> > +       odp_ipsec_policy_rule_action_t action;

>> > +       /** SPD Policy Action */

>> > +       odp_ipsec_policy_rule_position_t position;

>> > +       /** Position of this policy in policy table */

>> > +       odp_ipsec_policy_t relative_policy;

>> >

>>

>> odp_ipsec_policy_t does not appear to be defined here. It's also

>> referenced

>> in several APIs below.

>>

>>

>> > +       /** relative policy for the position in case of before/after */

>> > +       uint32_t n_dscp_ranges;

>> > +       /** Number of DSCP Ranges */

>> > +       struct odp_ipsec_policy_rule_dscprange *dscp_ranges;

>> > +       /** Array of DSCP Ranges */

>> > +       enum odp_ipsec_policy_redside_fragmentation redside;

>> > +       /** Fragmentation before Encapsulation option: TRUE/FALSE */

>> > +       uint32_t n_selectors;

>> > +       /** Number of selectors */

>> > +       const odp_pmr_param_t *selectors;

>> > +       /** Array of Selectors */

>> > +};

>> > +

>> > +/**

>> > + * Output parameters to SPD Policy addition

>> > + */

>> > +typedef struct odp_ipsec_spd_add_err{

>> >

>>

>> space before { (checkpatch)

>>

>>

>> > +       int32_t result;

>> > +       /** 0:Success; Non Zero value: Error code indicating failure */

>> > +}odp_ipsec_pol_add_err_t;

>> >

>>

>> space after } (checkpatch)

>>

>> Does this need to be a struct? Do we expect to expand this? Seems

>> cumbersome if the only output is a simple return code.

>>

>>

>> > +

>> > +/**

>> > + * @brief This API is used to add Inbound/Outbound SPD policy to SPD

>> > policy

>> > + * database.  This database is maintained per Name Space and Tunnel

>> > instance.

>> > + * This function first validates the incoming parameters

>> > + * and if all validations succeed, new SPD policy is added to the

>> > database.

>> > + *

>> > + * @param[in] params   Pointer to input param structure which contains

>> > + *                     spd policy information.

>> > + * @param[out] policy  Handle to the IPSEC policy.

>> > + * @param[out] resp    Failure code if unsuccessful.

>> > + *

>> > + * @returns 0 on Success or negative value on failure.

>> > + *

>> > + */

>> > +int32_t odp_ipsec_spd_add(

>> > +               const struct odp_ipsec_spd_params *params,

>> >

>>

>> should be const odp_ipsec_spd_param_t *params,

>>

>>

>> > +               odp_ipsec_policy_t *policy,

>> > +               odp_ipsec_pol_add_err_t *resp);

>> > +

>> > +/**

>> > + * @brief This API is used to delete Inbound/Outbound SPD policy from

>> SPD

>> > policy

>> > + * database.

>> > + *

>> > + * @param[in] policy   Handle to the IPSEC policy.

>> > + *

>> > + * @returns 0 on Success or negative value on failure.

>> > + *

>> > + */

>> > +int32_t odp_ipsec_spd_del(odp_ipsec_policy_t policy);

>> > +

>> > +/**

>> > + * @brief This API is used to flush/delete all Inbound and Outbound SPD

>> > + * policies.

>> > + *

>> > + * @returns 0 on Success or negative value on failure.

>> > + *

>> > + */

>> > +int32_t odp_ipsec_spd_flush();

>> >

>>

>> Syntax: must be odp_ipsec_spd_flush(void);

>>

>>

>> > +

>> > +/**

>> > + * @brief This API maps an IPSEC policy to an IPSEC crypto session.

>> > + *

>> > + * @param[in] policy - Handle to the IPSEC policy.

>> > + * @param[in] session - Handle to the IPSEC session(SA).

>> > + *

>> > + * @returns SUCCESS on success; FAILURE otherwise

>> > + *

>> > + */

>> > +int32_t odp_ipsec_map_pol_session(odp_ipsec_policy_t policy

>> >

>>

>> pol is an awkward abbreviation. odp_ipsec_map_policy_session() would seem

>> to be preferable here.

>>

>>

>> > +               odp_crypto_session_t session);

>> >

>>

>> See earlier comments regarding overload of odp_crypto_session_t type.

>>

>> +

>> > +/**

>> > + * @brief This API unmaps an IPSEC policy to an IPSEC crypto session.

>> >

>>

>> ...from an IPsec crypto session

>>

>>

>> > + *

>> > + * @param[in] policy - Handle to the IPSEC policy.

>> > + * @param[in] session - Handle to the IPSEC session(SA).

>> > + *

>> > + * @returns SUCCESS on success; FAILURE otherwise

>> > + *

>> > + */

>> > +int32_t odp_ipsec_unmap_pol_session(odp_ipsec_policy_t policy

>> >

>>

>> Again, odp_ipsec_unmap_policy_session()

>>

>>

>> > +               odp_crypto_session_t session);

>> >

>>

>> Same question on overload of this type.

>>

>>

>> > +

>> > +/**

>> > +  * ODP ipsec notification event type

>> > +  */

>> > +

>> > +typedef enum odp_ipsec_notif_type {

>> > +       ODP_IPSEC_NO_OUB_SA, /** IPSEC policy matched but Outbound SA

>> not

>> > found */

>> > +       ODP_IPSEC_NO_INB_SA, /** IPSEC policy matched but inbound SA not

>> > found */

>> > +       ODP_IPSEC_SA_SOFT_EXPIRY, /** SA soft expiry limit reached */

>> > +       ODP_IPSEC_SA_HARD_EXPIRY, /** SA hard expiry limit reached */

>> > +       ODP_IPSEC_SA_SEQ_NUM_OVERFLOW, /** Seq number overflow */

>> > +} odp_ipsec_notif_type_t;

>> > +

>> > +typedef struct odp_ipsec_notif_info {

>> > +       odp_ipsec_notif_type_t notif_type;

>> > +       odp_ipsec_policy_t policy;

>> > +       odp_ipsec_session_t session;

>> > +}odp_ipsec_notif_info_t;

>> >

>>

>> space after } (checkpatch)

>>

>>

>> > +

>> > +/**

>> > + * @brief This API gets notification queue for ODP IPSEC module.

>> > + *

>> > + * @param[out] queue - Handle to the IPSEC notification queue.

>> > + *

>> > + * @returns SUCCESS on success; FAILURE otherwise

>> > + *

>> > + */

>> > +int32_t odp_ipsec_get_notification_queue(odp_queue_t *queue);

>> > +

>> > +/**

>> > + * Return crypto notification handle that is associated with event

>> > + *

>> > + * Note: any invalid parameters will cause undefined behavior and may

>> > cause

>> > + * the application to abort or crash.

>> > + *

>> > + * @param ev An event of type ODP_EVENT_CRYPTO_NOTIF

>> > + *

>> > + * @return crypto completion handle

>> > + */

>> > +odp_crypto_notif_t odp_crypto_notif_from_event(odp_event_t ev);

>> > +

>> > +

>> > +/**

>> > + * Return notification info of this crypto notification event.

>> > + *

>> > + * @param[in] notif_ev An event of type ODP_EVENT_CRYPTO_NOTIF

>> > + * @param[out] notif_info structure populated with notification info

>> > + *

>> > + * @return success/failure

>> > + */

>> > +uint32_t odp_ipsec_notif_info_from_event(odp_crypto_notif_t notif_ev

>> > +               odp_ipsec_notif_info_t* notif_info);

>> > +

>> > +/**

>> > + * SPD Policy Statistics information structure

>> > + */

>> > +typedef struct odp_ipsec_spd_stats {

>> > +       uint64_t received_pkts;

>> > +       /** Received Outbound/Inbound packets */

>> > +       uint64_t processed_pkts;

>> > +       /** Processed Outbound/Inbound packets */

>> > +       uint64_t processed_bytes;

>> > +       /** Number of bytes processed on Inbound/Outbound policy */

>> > +

>> > +       /** Struct details

>> > +        */

>> > +       struct {

>> > +               uint32_t crypto_op_failed;

>> > +               /** Crypto operations failed */

>> > +       }protocol_violation_errors;

>> > +       /** Protocol violation errors */

>> > +

>> > +       /** Struct details

>> > +        */

>> > +       struct {

>> > +               uint32_t no_matching_dscp_range;

>> > +               /** Matching dscp range not found in the SPD policy */

>> > +

>> > +               uint32_t submit_to_sec_failed;

>> > +               /** Submission to SEC failed for crypto operations */

>> > +               uint32_t no_outb_sa;

>> > +               /** Outbound SA not found */

>> > +               uint32_t frag_failed;

>> > +               /** Fragmentation failed */

>> > +               uint32_t mem_alloc_failed;

>> > +               /** Memory allocation failed for SA/SPD/descriptor

>> etc.*/

>> > +               uint32_t internal_error;

>> > +               /** All other errors locally encountered */

>> > +       }local_errors;

>> > +       /** Local/internal errors */

>> > +

>> >

>>

>> No space here (checkpatch)

>>

>>

>> > +}odp_ipsec_spd_stats_t;

>> > +

>> > +/**

>> > + * @brief This API fetches global statistics.

>> > + *

>> > + * @param[out] stats  Pointer to statistics structure filled by this

>> API.

>> > + *

>> > + * @returns 0 on Success or negative value on failure.

>> > + *

>> > + */

>> > +int32_t odp_ipsec_global_stats_get(odp_ipsec_spd_stats_t *stats);

>> >

>>

>> No _get suffix on getters. So this should be odp_ipsec_global_stats()

>>

>>

>> > +

>> > +/**

>> > + * IPSec Module Capabilities

>> > + */

>> > +struct odp_ipsec_capabilities {

>> > +       /** This parameter indicates if IPSec-DP is capable of doing SPD

>> > +        * rule search for incoming or outgoing datagrams

>> > +        */

>> > +

>> > +       uint32_t sel_store_in_spd : 1,

>> > +

>> > +                /** Authentication Header processing */

>> > +                ah_protocol:1,

>> > +

>> > +                /** ESP Header processing */

>> > +                esp_protocol:1,

>> > +

>> > +                /** IPComp related processing */

>> > +                ipcomp_protocol:1,

>> > +

>> > +                /** IPSec Tunnel Mode processing */

>> > +                tunnel_mode:1,

>> > +

>> > +                /** IPSec Tunnel Mode processing */

>> > +                transport_mode:1,

>> > +

>> > +                /** This indicates if IPSec has capability to generate

>> > +                 * (for Outbound) and verify (for Inbound) extended

>> > sequence numbers.

>> > +                 */

>> > +                esn:1,

>> > +

>> > +                /** This option indicates whether IPSec can

>> > +                 * handle the necessary UDP Encapsulation required at

>> > +                 * IPSec level for traversing NAT boxes.

>> > +                 */

>> > +                udp_encap:1,

>> > +

>> > +                /** This option indicates whether IPSec can fragment

>> > packets

>> > +                 * before IPSec encryption, so that the resulting IPSec

>> > encrypted

>> > +                 * fragments do not exceed MTU

>> > +                 */

>> > +                redside_frag:1,

>> > +

>> > +

>> > +       /** Indicates the maximum number of IN and OUT SPD policies. */

>> > +       uint32_t            max_spd_policies;

>> > +

>> > +       /** Indicates the maximum number of IN and OUT IPSec SAs. */

>> > +       uint32_t             max_sas;

>> > +}odp_ipsec_capabilities_t;

>> >

>>

>> space after } (checkpatch)

>>

>> This should be odp_ipsec_capability_t for consistency with other

>> capability

>> structs.

>>

>>

>> > +

>> > +/**

>> > + * @brief This API fetches IPSec module Capabilities

>> > + *

>> > + * @param[out] capa - capabilities structure filled by API.

>> > + *

>> > + * @returns SUCCESS on success; FAILURE otherwise

>> > + *

>> > + */

>> > +int32_t odp_ipsec_capabilities_get(odp_ipsec_capabilities_t *capa);

>> >

>>

>> This should be named odp_ipsec_capability() for consistency with other

>> capability APIs.

>>

>>

>> > +

>> > +

>> > +#endif /* __IPSEC_API_H */

>> > +/**

>> > + * @}

>> > + */

>> > +

>> > +#ifdef __cplusplus

>> > +}

>> > +#endif

>> > +

>> > +#endif

>> > diff --git a/platform/linux-generic/include/odp/api/plat/event_types.h

>> > b/platform/linux-generic/include/odp/api/plat/event_types.h

>> > index 9ca0fb8..b083d3e 100644

>> > --- a/platform/linux-generic/include/odp/api/plat/event_types.h

>> > +++ b/platform/linux-generic/include/odp/api/plat/event_types.h

>> > @@ -38,6 +38,7 @@ typedef enum odp_event_type_t {

>> >         ODP_EVENT_PACKET       = 2,

>> >         ODP_EVENT_TIMEOUT      = 3,

>> >         ODP_EVENT_CRYPTO_COMPL = 4,

>> > +       ODP_EVENT_CRYPTO_notif = 5,

>> >

>>

>> Typo, as Josep previously noted.

>>

>>

>> >  } odp_event_type_t;

>> >

>> >  /** Get printable format of odp_event_t */

>> > --

>> > 2.9.3

>> >

>> >

>>

>

>

>

> --

> [image: Linaro] <http://www.linaro.org/>

> François-Frédéric Ozog | *Director Linaro Networking Group*

> T: +33.67221.6485

> francois.ozog@linaro.org | Skype: ffozog

>

>
diff mbox

Patch

diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h
index dea1fe9..3a67d92 100644
--- a/include/odp/api/spec/crypto.h
+++ b/include/odp/api/spec/crypto.h
@@ -144,6 +144,27 @@  typedef union odp_crypto_auth_algos_t {
 	uint32_t all_bits;
 } odp_crypto_auth_algos_t;
 
+
+/**
+ * Network security protocols in bit field structure
+ */
+typedef union odp_crypto_protocol_t {
+	/** Network security protocols */
+	struct {
+		/** ESP Protocol */
+		uint32_t ipsec_esp    : 1;
+
+		/** AH protocol */
+		uint32_t ipsec_ah     : 1;
+
+	} bit;
+
+	/** All bits of the bit field structure
+	  *
+	  * This field can be used to set/clear all flags, or bitwise
+	  * operations over the entire structure. */
+	uint32_t all_bits;
+} odp_crypto_protocol_t;
 /**
  * Crypto API key structure
  */
@@ -264,6 +285,8 @@  typedef enum {
 	ODP_CRYPTO_SES_CREATE_ERR_INV_CIPHER,
 	/** Creation failed, bad auth params */
 	ODP_CRYPTO_SES_CREATE_ERR_INV_AUTH,
+	/** Creation failed, bad protocol params */
+	ODP_CRYPTO_SES_CREATE_ERR_INV_PROTO,
 } odp_crypto_ses_create_err_t;
 
 /**
@@ -332,6 +355,12 @@  typedef struct odp_crypto_capability_t {
 	/** Authentication algorithms implemented with HW offload */
 	odp_crypto_auth_algos_t   hw_auths;
 
+	/** Supported authentication algorithms */
+	odp_crypto_protocol_t   protocols;
+
+	/** Authentication algorithms implemented with HW offload */
+	odp_crypto_protocol_t   hw_protocols;
+
 } odp_crypto_capability_t;
 
 /**
diff --git a/include/odp/api/spec/crypto_ipsec.h b/include/odp/api/spec/crypto_ipsec.h
new file mode 100644
index 0000000..5916ea0
--- /dev/null
+++ b/include/odp/api/spec/crypto_ipsec.h
@@ -0,0 +1,449 @@ 
+/* Copyright (c) 2014, Linaro Limited
+ * Copyright (c) 2015 - 2016 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP crypto IPSec extension
+ */
+
+#ifndef ODP_API_CRYPTO_IPSEC_H_
+#define ODP_API_CRYPTO_IPSEC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef enum odp_ipsec_mode {
+	ODP_IPSEC_MODE_TUNNEL,	    /** IPSec tunnel mode */
+	ODP_IPSEC_MODE_TRANSPORT,   /** IPSec transport mode */
+} odp_ipsec_mode_t;
+
+typedef enum odp_ipsec_proto {
+	ODP_IPSEC_ESP,		   /** ESP protocol */
+	ODP_IPSEC_AH,		   /** AH protocol */
+} odp_ipsec_proto_t;
+
+typedef enum odp_ipsec_outhdr_type {
+	ODP_IPSEC_OUTHDR_IPV4,	  /** Outer header is IPv4 */
+	ODP_IPSEC_OUTHDR_IPV6,	  /** Outer header is IPv6 */
+} odp_ipsec_outhdr_type_t;
+
+/**
+  * ODP IPSEC flags bit feilds structure
+  */
+
+typedef struct odp_ipsec_session_flags {
+	uint32_t esn : 1;
+	/** When enabled, extended sequence numbers is used */
+	uint32_t nat_t : 1;
+	/** When enabled, this indicates that UDP encapsulation/decapsulation
+	  * for IPSEC packet has to be done so that IPSEC packet can traverse
+	  * through NAT boxes. UDP encapsulation/decapsulation is to be applied
+	  * for packets that get processed off this SA.
+	  */
+	uint32_t copy_dscp : 1;
+	/** When enabled, Copy the IPv4 TOS or IPv6 Traffic Class byte from
+	  * inner/outer IP header to the outer/inner IP header. If disabled
+	  * values from configured Header will be used */
+	uint32_t copy_df : 1;
+	/** When enabled, copy the DF bit from the inner IP header to the outer
+	  * IP header. If disabled, values from configured Header will be used */
+
+	uint32_t ip_dttl : 1;
+	/** When enabled,IPv4 ttl/IPv6 Hop Limit feild will be decremented
+	  * in case of tunnel mode encap & decap */
+
+	uint32_t remove_outer_hdr : 1;
+	/** remove outer header - tunnel mode decap */
+
+	uint32_t verify_sa_selectors : 1;
+	/** This flag is only application to inbound sessions. When enabled,
+	  * this indicates that post decryption, selectors needs to be verified
+	  * for this session. */
+
+} odp_ipsec_session_flags_t;
+
+typedef enum odp_ipsec_sa_lifetime_type {
+	ODP_IPSEC_SA_LIFETIME_IN_SEC, /** SA life time is in seconds */
+	ODP_IPSEC_SA_LIFETIME_IN_KB,  /** SA life time is in kilo bytes */
+	ODP_IPSEC_SA_LIFETIME_IN_PKT_CNT, /** SA life time is in packet count */
+} odp_ipsec_sa_lifetime_type_t;
+
+typedef struct odp_ipsec_params {
+	odp_ipsec_mode_t ipsec_mode; /** Transport or Tunnel */
+	odp_ipsec_proto_t ipsec_proto; /** IPSEC protocol ESP/AH */
+	uint64_t seq;		 /** Initial SEQ number */
+	uint32_t spi;		 /** SPI value */
+	uint16_t ar_ws; /** Anti-replay window size. Value 0 indicates that
+			  Anti-replay window check is disabled for this SA */
+	uint16_t out_hdr_size;	 /** outer header size - tunnel mode */
+	uint8_t *out_hdr;	 /** outer header - tunnel mode */
+	odp_ipsec_outhdr_type_t out_hdr_type; /** outer header type tunnel mode*/
+	odp_ipsec_session_flags_t sa_flags; /** SA control flags */
+	odp_ipsec_sa_lifetime_type_t lifetime_type; /** lifetime type */
+	uint64_t soft_expiry_limit;
+	/** Soft expiry for this session, values may be in seconds, Kilobytes or
+	  * number of packets depending on feild odp_ipsec_sa_lifetime_type_t */
+	uint64_t hard_expiry_limit;
+	/** Hard expiry for this session, values may be in seconds, Kilobytes or
+	  * number of packets depending on feild odp_ipsec_sa_lifetime_type_t */
+
+} odp_ipsec_params_t;
+
+/**
+ * Configure crypto session for IPsec processing
+ *
+ * Configures a crypto session for IPSec protocol processing.
+ * Packets submitted to an IPSec enabled session will have
+ * relevant IPSec headers/trailers and tunnel headers
+ * added/removed by the crypto implementation.
+ * For example, the input packet for an IPSec ESP transport
+ * enabled session should be the clear text packet with
+ * no ESP headers/trailers prepared in advance for crypto operation.
+ * The output packet will have ESP header, IV, trailer and the ESP ICV
+ * added by crypto implementation.
+ * Depending on the particular capabilities of an implementation and
+ * the parameters enabled by application, the application may be
+ * partially or completely offloaded from IPSec protocol processing.
+ * For example, if an implementation does not support checksum
+ * update for IP header after adding ESP header the application
+ * should update after crypto IPSec operation.
+ *
+ * If an implementation does not support a particular set of
+ * arguments it should return error.
+ *
+ * @param session	    Session handle
+ * @param ipsec_params	    IPSec parameters. Parameters which are not
+ *			    relevant for selected protocol & mode are ignored -
+ *			    e.g. outer_hdr/size set for ESP transport mode.
+ * @retval 0 on success
+ * @retval <0 on failure
+ */
+int odp_crypto_ipsec_session_create(odp_crypto_session_params_t *ses_params,
+				    odp_ipsec_params_t *ipsec_params,
+				    odp_crypto_session_t *session_out,
+				    odp_crypto_ses_create_err_t *status);
+
+
+/**
+ * SPD Policy/SA direction information
+ */
+typedef enum odp_ipsec_direction {
+	ODP_IPSEC_INBOUND, 	/** Inbound Direction */
+	ODP_IPSEC_OUTBOUND 	/** Outbound Direction */
+}odp_ipsec_direction_t;
+
+/**
+ * SPD Policy Action information
+ */
+typedef enum odp_ipsec_policy_rule_action {
+	ODP_IPSEC_POLICY_ACTION_IPSEC, /** Apply IPSec processing on Packet*/
+	ODP_IPSEC_POLICY_ACTION_DISCARD, /** Discard or Drop the packet */
+	ODP_IPSEC_POLICY_ACTION_BYPASS, /** Bypass/Allow to pass the packet */
+}odp_ipsec_policy_rule_action_t;
+
+/**
+ * SPD Policy Position information
+ */
+typedef enum odp_ipsec_policy_rule_position{
+	ODP_IPSEC_POLICY_POSITION_BEGIN, /** Add at the beginning of the list */
+	ODP_IPSEC_POLICY_POSITION_BEFORE, /** Add before the mentioned Policy */
+	ODP_IPSEC_POLICY_POSITION_AFTER, /** Add after the mentioned Policy */
+	ODP_IPSEC_POLICY_POSITION_END, /** Add at the end of the list */
+} odp_ipsec_policy_rule_position_t;
+
+
+/**
+ * DSCP Range information
+ */
+typedef struct odp_ipsec_policy_rule_dscprange {
+	uint8_t start; 	/** Start value in Range */
+	uint8_t end; 	/** End value  in Range */
+}odp_ipsec_policy_rule_dscprange_t;
+
+/**
+ * Fragmentation Before Encapsulation (Redside Fragmentation)
+ */
+typedef enum odp_ipsec_policy_redside_fragmentation {
+	ODP_IPSEC_POLICY_REDSIDE_FRAGMENTATION_DISABLE = 0,
+	/** Disable Redside fragmentation in IPSec Policy */
+	ODP_IPSEC_POLICY_REDSIDE_FRAGMENTATION_ENABLE
+		/** Enable Redside fragmentation in IPSec Policy */
+}odp_ipsec_policy_redside_fragmentation_t;
+
+/**
+ * Input parameters to SPD Policy addition
+ */
+struct odp_ipsec_spd_params{
+	uint32_t tunnel_id;
+	/** Tunnel ID */
+	odp_ipsec_direction_t dir;
+	/** Direction: Inbound or Outbound */
+	odp_ipsec_policy_rule_action_t action;
+	/** SPD Policy Action */
+	odp_ipsec_policy_rule_position_t position;
+	/** Position of this policy in policy table */
+	odp_ipsec_policy_t relative_policy;
+	/** relative policy for the position in case of before/after */
+	uint32_t n_dscp_ranges;
+	/** Number of DSCP Ranges */
+	struct odp_ipsec_policy_rule_dscprange *dscp_ranges;
+	/** Array of DSCP Ranges */
+	enum odp_ipsec_policy_redside_fragmentation redside;
+	/** Fragmentation before Encapsulation option: TRUE/FALSE */
+	uint32_t n_selectors;
+	/** Number of selectors */
+	const odp_pmr_param_t *selectors;
+	/** Array of Selectors */
+};
+
+/**
+ * Output parameters to SPD Policy addition
+ */
+typedef struct odp_ipsec_spd_add_err{
+	int32_t result;
+	/** 0:Success; Non Zero value: Error code indicating failure */
+}odp_ipsec_pol_add_err_t;
+
+/**
+ * @brief This API is used to add Inbound/Outbound SPD policy to SPD policy
+ * database.  This database is maintained per Name Space and Tunnel instance.
+ * This function first validates the incoming parameters
+ * and if all validations succeed, new SPD policy is added to the database.
+ *
+ * @param[in] params	Pointer to input param structure which contains
+ *			spd policy information.
+ * @param[out] policy 	Handle to the IPSEC policy.
+ * @param[out] resp	Failure code if unsuccessful.
+ *
+ * @returns 0 on Success or negative value on failure.
+ *
+ */
+int32_t odp_ipsec_spd_add(
+		const struct odp_ipsec_spd_params *params,
+		odp_ipsec_policy_t *policy,
+		odp_ipsec_pol_add_err_t *resp);
+
+/**
+ * @brief This API is used to delete Inbound/Outbound SPD policy from SPD policy
+ * database.
+ *
+ * @param[in] policy 	Handle to the IPSEC policy.
+ *
+ * @returns 0 on Success or negative value on failure.
+ *
+ */
+int32_t odp_ipsec_spd_del(odp_ipsec_policy_t policy);
+
+/**
+ * @brief This API is used to flush/delete all Inbound and Outbound SPD
+ * policies.
+ *
+ * @returns 0 on Success or negative value on failure.
+ *
+ */
+int32_t odp_ipsec_spd_flush();
+
+/**
+ * @brief This API maps an IPSEC policy to an IPSEC crypto session.
+ *
+ * @param[in] policy - Handle to the IPSEC policy.
+ * @param[in] session - Handle to the IPSEC session(SA).
+ *
+ * @returns SUCCESS on success; FAILURE otherwise
+ *
+ */
+int32_t odp_ipsec_map_pol_session(odp_ipsec_policy_t policy
+		odp_crypto_session_t session);
+
+/**
+ * @brief This API unmaps an IPSEC policy to an IPSEC crypto session.
+ *
+ * @param[in] policy - Handle to the IPSEC policy.
+ * @param[in] session - Handle to the IPSEC session(SA).
+ *
+ * @returns SUCCESS on success; FAILURE otherwise
+ *
+ */
+int32_t odp_ipsec_unmap_pol_session(odp_ipsec_policy_t policy
+		odp_crypto_session_t session);
+
+/**
+  * ODP ipsec notification event type
+  */
+
+typedef enum odp_ipsec_notif_type {
+	ODP_IPSEC_NO_OUB_SA, /** IPSEC policy matched but Outbound SA not found */
+	ODP_IPSEC_NO_INB_SA, /** IPSEC policy matched but inbound SA not found */
+	ODP_IPSEC_SA_SOFT_EXPIRY, /** SA soft expiry limit reached */
+	ODP_IPSEC_SA_HARD_EXPIRY, /** SA hard expiry limit reached */
+	ODP_IPSEC_SA_SEQ_NUM_OVERFLOW, /** Seq number overflow */
+} odp_ipsec_notif_type_t;
+
+typedef struct odp_ipsec_notif_info {
+	odp_ipsec_notif_type_t notif_type;
+	odp_ipsec_policy_t policy;
+	odp_ipsec_session_t session;
+}odp_ipsec_notif_info_t;
+
+/**
+ * @brief This API gets notification queue for ODP IPSEC module.
+ *
+ * @param[out] queue - Handle to the IPSEC notification queue.
+ *
+ * @returns SUCCESS on success; FAILURE otherwise
+ *
+ */
+int32_t odp_ipsec_get_notification_queue(odp_queue_t *queue);
+
+/**
+ * Return crypto notification handle that is associated with event
+ *
+ * Note: any invalid parameters will cause undefined behavior and may cause
+ * the application to abort or crash.
+ *
+ * @param ev An event of type ODP_EVENT_CRYPTO_NOTIF
+ *
+ * @return crypto completion handle
+ */
+odp_crypto_notif_t odp_crypto_notif_from_event(odp_event_t ev);
+
+
+/**
+ * Return notification info of this crypto notification event.
+ *
+ * @param[in] notif_ev An event of type ODP_EVENT_CRYPTO_NOTIF
+ * @param[out] notif_info structure populated with notification info
+ *
+ * @return success/failure
+ */
+uint32_t odp_ipsec_notif_info_from_event(odp_crypto_notif_t notif_ev
+		odp_ipsec_notif_info_t* notif_info);
+
+/**
+ * SPD Policy Statistics information structure
+ */
+typedef struct odp_ipsec_spd_stats {
+	uint64_t received_pkts;
+	/** Received Outbound/Inbound packets */
+	uint64_t processed_pkts;
+	/** Processed Outbound/Inbound packets */
+	uint64_t processed_bytes;
+	/** Number of bytes processed on Inbound/Outbound policy */
+
+	/** Struct details
+	 */
+	struct {
+		uint32_t crypto_op_failed;
+		/** Crypto operations failed */
+	}protocol_violation_errors;
+	/** Protocol violation errors */
+
+	/** Struct details
+	 */
+	struct {
+		uint32_t no_matching_dscp_range;
+		/** Matching dscp range not found in the SPD policy */
+
+		uint32_t submit_to_sec_failed;
+		/** Submission to SEC failed for crypto operations */
+		uint32_t no_outb_sa;
+		/** Outbound SA not found */
+		uint32_t frag_failed;
+		/** Fragmentation failed */
+		uint32_t mem_alloc_failed;
+		/** Memory allocation failed for SA/SPD/descriptor etc.*/
+		uint32_t internal_error;
+		/** All other errors locally encountered */
+	}local_errors;
+	/** Local/internal errors */
+
+}odp_ipsec_spd_stats_t;
+
+/**
+ * @brief This API fetches global statistics.
+ *
+ * @param[out] stats  Pointer to statistics structure filled by this API.
+ *
+ * @returns 0 on Success or negative value on failure.
+ *
+ */
+int32_t odp_ipsec_global_stats_get(odp_ipsec_spd_stats_t *stats);
+
+/**
+ * IPSec Module Capabilities
+ */
+struct odp_ipsec_capabilities {
+	/** This parameter indicates if IPSec-DP is capable of doing SPD
+	 * rule search for incoming or outgoing datagrams
+	 */
+
+	uint32_t sel_store_in_spd : 1,
+
+		 /** Authentication Header processing */
+		 ah_protocol:1,
+
+		 /** ESP Header processing */
+		 esp_protocol:1,
+
+		 /** IPComp related processing */
+		 ipcomp_protocol:1,
+
+		 /** IPSec Tunnel Mode processing */
+		 tunnel_mode:1,
+
+		 /** IPSec Tunnel Mode processing */
+		 transport_mode:1,
+
+		 /** This indicates if IPSec has capability to generate
+		  * (for Outbound) and verify (for Inbound) extended sequence numbers.
+		  */
+		 esn:1,
+
+		 /** This option indicates whether IPSec can
+		  * handle the necessary UDP Encapsulation required at
+		  * IPSec level for traversing NAT boxes.
+		  */
+		 udp_encap:1,
+
+		 /** This option indicates whether IPSec can fragment packets
+		  * before IPSec encryption, so that the resulting IPSec encrypted
+		  * fragments do not exceed MTU
+		  */
+		 redside_frag:1,
+
+
+	/** Indicates the maximum number of IN and OUT SPD policies. */
+	uint32_t	    max_spd_policies;
+
+	/** Indicates the maximum number of IN and OUT IPSec SAs. */
+	uint32_t	     max_sas;
+}odp_ipsec_capabilities_t;
+
+/**
+ * @brief This API fetches IPSec module Capabilities
+ *
+ * @param[out] capa - capabilities structure filled by API.
+ *
+ * @returns SUCCESS on success; FAILURE otherwise
+ *
+ */
+int32_t odp_ipsec_capabilities_get(odp_ipsec_capabilities_t *capa);
+
+
+#endif /* __IPSEC_API_H */
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/include/odp/api/plat/event_types.h b/platform/linux-generic/include/odp/api/plat/event_types.h
index 9ca0fb8..b083d3e 100644
--- a/platform/linux-generic/include/odp/api/plat/event_types.h
+++ b/platform/linux-generic/include/odp/api/plat/event_types.h
@@ -38,6 +38,7 @@  typedef enum odp_event_type_t {
 	ODP_EVENT_PACKET       = 2,
 	ODP_EVENT_TIMEOUT      = 3,
 	ODP_EVENT_CRYPTO_COMPL = 4,
+	ODP_EVENT_CRYPTO_notif = 5,
 } odp_event_type_t;
 
 /** Get printable format of odp_event_t */