/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef __IPSEC_SPD_SA_H__
#define __IPSEC_SPD_SA_H__

#include <vlib/vlib.h>
#include <vnet/ip/ip.h>
#include <vnet/fib/fib_node.h>

#define foreach_ipsec_crypto_alg    \
  _ (0, NONE, "none")               \
  _ (1, AES_CBC_128, "aes-cbc-128") \
  _ (2, AES_CBC_192, "aes-cbc-192") \
  _ (3, AES_CBC_256, "aes-cbc-256") \
  _ (4, AES_CTR_128, "aes-ctr-128") \
  _ (5, AES_CTR_192, "aes-ctr-192") \
  _ (6, AES_CTR_256, "aes-ctr-256") \
  _ (7, AES_GCM_128, "aes-gcm-128") \
  _ (8, AES_GCM_192, "aes-gcm-192") \
  _ (9, AES_GCM_256, "aes-gcm-256") \
  _ (10, DES_CBC, "des-cbc")        \
  _ (11, 3DES_CBC, "3des-cbc")

typedef enum
{
#define _(v, f, s) IPSEC_CRYPTO_ALG_##f = v,
  foreach_ipsec_crypto_alg
#undef _
    IPSEC_CRYPTO_N_ALG,
} ipsec_crypto_alg_t;

#define IPSEC_CRYPTO_ALG_IS_GCM(_alg)                     \
  (((_alg == IPSEC_CRYPTO_ALG_AES_GCM_128) ||             \
    (_alg == IPSEC_CRYPTO_ALG_AES_GCM_192) ||             \
    (_alg == IPSEC_CRYPTO_ALG_AES_GCM_256)))

#define foreach_ipsec_integ_alg                                            \
  _ (0, NONE, "none")                                                      \
  _ (1, MD5_96, "md5-96")           /* RFC2403 */                          \
  _ (2, SHA1_96, "sha1-96")         /* RFC2404 */                          \
  _ (3, SHA_256_96, "sha-256-96")   /* draft-ietf-ipsec-ciph-sha-256-00 */ \
  _ (4, SHA_256_128, "sha-256-128") /* RFC4868 */                          \
  _ (5, SHA_384_192, "sha-384-192") /* RFC4868 */                          \
  _ (6, SHA_512_256, "sha-512-256")	/* RFC4868 */

typedef enum
{
#define _(v, f, s) IPSEC_INTEG_ALG_##f = v,
  foreach_ipsec_integ_alg
#undef _
    IPSEC_INTEG_N_ALG,
} ipsec_integ_alg_t;

typedef enum
{
  IPSEC_PROTOCOL_AH = 0,
  IPSEC_PROTOCOL_ESP = 1
} ipsec_protocol_t;

#define IPSEC_KEY_MAX_LEN 128
typedef struct ipsec_key_t_
{
  u8 len;
  u8 data[IPSEC_KEY_MAX_LEN];
} ipsec_key_t;

/*
 * Enable extended sequence numbers
 * Enable Anti-replay
 * IPsec tunnel mode if non-zero, else transport mode
 * IPsec tunnel mode is IPv6 if non-zero,
 * else IPv4 tunnel only valid if is_tunnel is non-zero
 * enable UDP encapsulation for NAT traversal
 */
#define foreach_ipsec_sa_flags                            \
  _ (0, NONE, "none")                                     \
  _ (1, USE_ESN, "esn")                                   \
  _ (2, USE_ANTI_REPLAY, "anti-replay")                   \
  _ (4, IS_TUNNEL, "tunnel")                              \
  _ (8, IS_TUNNEL_V6, "tunnel-v6")                        \
  _ (16, UDP_ENCAP, "udp-encap")                          \
  _ (32, IS_PROTECT, "Protect")                           \
  _ (64, IS_INBOUND, "inbound")                           \
  _ (128, IS_AEAD, "aead")                                \

typedef enum ipsec_sad_flags_t_
{
#define _(v, f, s) IPSEC_SA_FLAG_##f = v,
  foreach_ipsec_sa_flags
#undef _
} __clib_packed ipsec_sa_flags_t;

STATIC_ASSERT (sizeof (ipsec_sa_flags_t) == 1, "IPSEC SA flags > 1 byte");

typedef struct
{
  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);

  /* flags */
  ipsec_sa_flags_t flags;

  u8 crypto_iv_size;
  u8 crypto_block_size;
  u8 integ_icv_size;
  u32 spi;
  u32 seq;
  u32 seq_hi;
  u32 last_seq;
  u32 last_seq_hi;
  u64 replay_window;
  dpo_id_t dpo;

  vnet_crypto_key_index_t crypto_key_index;
  vnet_crypto_key_index_t integ_key_index;
  vnet_crypto_op_id_t crypto_enc_op_id:16;
  vnet_crypto_op_id_t crypto_dec_op_id:16;
  vnet_crypto_op_id_t integ_op_id:16;

  /* data accessed by dataplane code should be above this comment */
    CLIB_CACHE_LINE_ALIGN_MARK (cacheline1);

  union
  {
    ip4_header_t ip4_hdr;
    ip6_header_t ip6_hdr;
  };
  udp_header_t udp_hdr;

  fib_node_t node;
  u32 id;
  u32 stat_index;
  ipsec_protocol_t protocol;

  ipsec_crypto_alg_t crypto_alg;
  ipsec_key_t crypto_key;
  vnet_crypto_alg_t crypto_calg;

  ipsec_integ_alg_t integ_alg;
  ipsec_key_t integ_key;
  vnet_crypto_alg_t integ_calg;

  ip46_address_t tunnel_src_addr;
  ip46_address_t tunnel_dst_addr;

  fib_node_index_t fib_entry_index;
  u32 sibling;

  u32 tx_fib_index;

  /* Salt used in GCM modes - stored in network byte order */
  u32 salt;
  u64 gcm_iv_counter;
} ipsec_sa_t;

STATIC_ASSERT_OFFSET_OF (ipsec_sa_t, cacheline1, CLIB_CACHE_LINE_BYTES);

#define _(a,v,s)                                                        \
  always_inline int                                                     \
  ipsec_sa_is_set_##v (const ipsec_sa_t *sa) {                          \
    return (sa->flags & IPSEC_SA_FLAG_##v);                             \
  }
foreach_ipsec_sa_flags
#undef _
#define _(a,v,s)                                                        \
  always_inline int                                                     \
  ipsec_sa_set_##v (ipsec_sa_t *sa) {                                   \
    return (sa->flags |= IPSEC_SA_FLAG_##v);                            \
  }
  foreach_ipsec_sa_flags
#undef _
#define _(a,v,s)                                                        \
  always_inline int                                                     \
  ipsec_sa_unset_##v (ipsec_sa_t *sa) {                                 \
    return (sa->flags &= ~IPSEC_SA_FLAG_##v);                           \
  }
  foreach_ipsec_sa_flags
#undef _
/**
 * @brief
 * SA packet & bytes counters
 */
extern vlib_combined_counter_main_t ipsec_sa_counters;

extern void ipsec_mk_key (ipsec_key_t * key, const u8 * data, u8 len);

extern int ipsec_sa_add_and_lock (u32 id,
				  u32 spi,
				  ipsec_protocol_t proto,
				  ipsec_crypto_alg_t crypto_alg,
				  const ipsec_key_t * ck,
				  ipsec_integ_alg_t integ_alg,
				  const ipsec_key_t * ik,
				  ipsec_sa_flags_t flags,
				  u32 tx_table_id,
				  u32 salt,
				  const ip46_address_t * tunnel_src_addr,
				  const ip46_address_t * tunnel_dst_addr,
				  u32 * sa_index);
extern index_t ipsec_sa_find_and_lock (u32 id);
extern int ipsec_sa_unlock_id (u32 id);
extern void ipsec_sa_unlock (index_t sai);
extern void ipsec_sa_lock (index_t sai);
extern void ipsec_sa_clear (index_t sai);
extern void ipsec_sa_set_crypto_alg (ipsec_sa_t * sa,
				     ipsec_crypto_alg_t crypto_alg);
extern void ipsec_sa_set_integ_alg (ipsec_sa_t * sa,
				    ipsec_integ_alg_t integ_alg);

typedef walk_rc_t (*ipsec_sa_walk_cb_t) (ipsec_sa_t * sa, void *ctx);
extern void ipsec_sa_walk (ipsec_sa_walk_cb_t cd, void *ctx);

extern u8 *format_ipsec_crypto_alg (u8 * s, va_list * args);
extern u8 *format_ipsec_integ_alg (u8 * s, va_list * args);
extern u8 *format_ipsec_sa (u8 * s, va_list * args);
extern u8 *format_ipsec_key (u8 * s, va_list * args);
extern uword unformat_ipsec_crypto_alg (unformat_input_t * input,
					va_list * args);
extern uword unformat_ipsec_integ_alg (unformat_input_t * input,
				       va_list * args);
extern uword unformat_ipsec_key (unformat_input_t * input, va_list * args);

/*
 * Anti Replay definitions
 */

#define IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE (64)
#define IPSEC_SA_ANTI_REPLAY_WINDOW_MAX_INDEX (IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE-1)

/*
 * sequence number less than the lower bound are outside of the window
 * From RFC4303 Appendix A:
 *  Bl = Tl - W + 1
 */
#define IPSEC_SA_ANTI_REPLAY_WINDOW_LOWER_BOUND(_tl) (_tl - IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE + 1)

/*
 * Anti replay check.
 *  inputs need to be in host byte order.
 */
always_inline int
ipsec_sa_anti_replay_check (ipsec_sa_t * sa, u32 seq)
{
  u32 diff, tl, th;

  if ((sa->flags & IPSEC_SA_FLAG_USE_ANTI_REPLAY) == 0)
    return 0;

  if (!ipsec_sa_is_set_USE_ESN (sa))
    {
      if (PREDICT_TRUE (seq > sa->last_seq))
	return 0;

      diff = sa->last_seq - seq;

      if (IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE > diff)
	return (sa->replay_window & (1ULL << diff)) ? 1 : 0;
      else
	return 1;

      return 0;
    }

  tl = sa->last_seq;
  th = sa->last_seq_hi;
  diff = tl - seq;

  if (PREDICT_TRUE (tl >= (IPSEC_SA_ANTI_REPLAY_WINDOW_MAX_INDEX)))
    {
      /*
       * the last sequence number VPP recieved is more than one
       * window size greater than zero.
       * Case A from RFC4303 Appendix A.
       */
      if (seq < IPSEC_SA_ANTI_REPLAY_WINDOW_LOWER_BOUND (tl))
	{
	  /*
	   * the received sequence number is lower than the lower bound
	   * of the window, this could mean either a replay packet or that
	   * the high sequence number has wrapped. if it decrypts corrently
	   * then it's the latter.
	   */
	  sa->seq_hi = th + 1;
	  return 0;
	}
      else
	{
	  /*
	   * the recieved sequence number greater than the low
	   * end of the window.
	   */
	  sa->seq_hi = th;
	  if (seq <= tl)
	    /*
	     * The recieved seq number is within bounds of the window
	     * check if it's a duplicate
	     */
	    return (sa->replay_window & (1ULL << diff)) ? 1 : 0;
	  else
	    /*
	     * The received sequence number is greater than the window
	     * upper bound. this packet will move the window along, assuming
	     * it decrypts correctly.
	     */
	    return 0;
	}
    }
  else
    {
      /*
       * the last sequence number VPP recieved is within one window
       * size of zero, i.e. 0 < TL < WINDOW_SIZE, the lower bound is thus a
       * large sequence number.
       * Note that the check below uses unsiged integer arthimetic, so the
       * RHS will be a larger number.
       * Case B from RFC4303 Appendix A.
       */
      if (seq < IPSEC_SA_ANTI_REPLAY_WINDOW_LOWER_BOUND (tl))
	{
	  /*
	   * the sequence number is less than the lower bound.
	   */
	  if (seq <= tl)
	    {
	      /*
	       * the packet is within the window upper bound.
	       * check for duplicates.
	       */
	      sa->seq_hi = th;
	      return (sa->replay_window & (1ULL << diff)) ? 1 : 0;
	    }
	  else
	    {
	      /*
	       * the packet is less the window lower bound or greater than
	       * the higher bound, depending on how you look at it...
	       * We're assuming, given that the last sequence number received,
	       * TL < WINDOW_SIZE, that a largeer seq num is more likely to be
	       * a packet that moves the window forward, than a packet that has
	       * wrapped the high sequence again. If it were the latter then
	       * we've lost close to 2^32 packets.
	       */
	      sa->seq_hi = th;
	      return 0;
	    }
	}
      else
	{
	  /*
	   * the packet seq number is between the lower bound (a large nubmer)
	   * and MAX_SEQ_NUM. This is in the window since the window upper bound
	   * tl > 0.
	   * However, since TL is the other side of 0 to the received
	   * packet, the SA has moved on to a higher sequence number.
	   */
	  sa->seq_hi = th - 1;
	  return (sa->replay_window & (1ULL << diff)) ? 1 : 0;
	}
    }

  return 0;
}

/*
 * Anti replay window advance
 *  inputs need to be in host byte order.
 */
always_inline void
ipsec_sa_anti_replay_advance (ipsec_sa_t * sa, u32 seq)
{
  u32 pos;
  if (PREDICT_TRUE (sa->flags & IPSEC_SA_FLAG_USE_ANTI_REPLAY) == 0)
    return;

  if (PREDICT_TRUE (sa->flags & IPSEC_SA_FLAG_USE_ESN))
    {
      int wrap = sa->seq_hi - sa->last_seq_hi;

      if (wrap == 0 && seq > sa->last_seq)
	{
	  pos = seq - sa->last_seq;
	  if (pos < IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE)
	    sa->replay_window = ((sa->replay_window) << pos) | 1;
	  else
	    sa->replay_window = 1;
	  sa->last_seq = seq;
	}
      else if (wrap > 0)
	{
	  pos = ~seq + sa->last_seq + 1;
	  if (pos < IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE)
	    sa->replay_window = ((sa->replay_window) << pos) | 1;
	  else
	    sa->replay_window = 1;
	  sa->last_seq = seq;
	  sa->last_seq_hi = sa->seq_hi;
	}
      else if (wrap < 0)
	{
	  pos = ~seq + sa->last_seq + 1;
	  sa->replay_window |= (1ULL << pos);
	}
      else
	{
	  pos = sa->last_seq - seq;
	  sa->replay_window |= (1ULL << pos);
	}
    }
  else
    {
      if (seq > sa->last_seq)
	{
	  pos = seq - sa->last_seq;
	  if (pos < IPSEC_SA_ANTI_REPLAY_WINDOW_SIZE)
	    sa->replay_window = ((sa->replay_window) << pos) | 1;
	  else
	    sa->replay_window = 1;
	  sa->last_seq = seq;
	}
      else
	{
	  pos = sa->last_seq - seq;
	  sa->replay_window |= (1ULL << pos);
	}
    }
}

#endif /* __IPSEC_SPD_SA_H__ */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
