For IPSEC anti-replay detection, if the sequence number is less than the lowest sequence in the window, is the packet dropped or accepted?
I assume it should be dropped, but for ESN packets it seems that the packet is accepted. In the xfrm implementation in the linux kernel if seq < bottom then the packet is accepted.
Below I have put the code for reference: https://elixir.bootlin.com/linux/v4.18-rc3/source/net/xfrm/xfrm_replay.c#L435
static int xfrm_replay_check_esn(struct xfrm_state *x,
struct sk_buff *skb, __be32 net_seq)
{
unsigned int bitnr, nr;
u32 diff;
struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
u32 pos;
u32 seq = ntohl(net_seq);
u32 wsize = replay_esn->replay_window;
u32 top = replay_esn->seq;
u32 bottom = top - wsize + 1;
if (!wsize)
return 0;
if (unlikely(seq == 0 && replay_esn->seq_hi == 0 &&
(replay_esn->seq < replay_esn->replay_window - 1)))
goto err;
diff = top - seq;
if (likely(top >= wsize - 1)) {
/* A. same subspace */
if (likely(seq > top) || seq < bottom)
return 0;
} else {
/* B. window spans two subspaces */
if (likely(seq > top && seq < bottom))
return 0;
if (seq >= bottom)
diff = ~seq + top + 1;
}
I am not sure what RFC4303 is expecting too:
Under Case A: If Seql >= Bl (where Bl = Tl - W + 1) AND Seql <=
Tl, then check the corresponding bit in the window to see if
this Seql has already been seen. If yes, reject the packet. If
no, perform integrity check (see Appendix A2.2. below for
determination of Seqh).