对于IPSEC抗重播检测,如果序列号小于窗口中的最低序列号,那么是否丢弃或接受了数据包?
我认为应该将其丢弃,但是对于ESN数据包,似乎该数据包已被接受。
在linux内核的xfrm实现中,如果seq 下面,我将代码用作参考:
this 我不确定RFC4303也期望什么: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;
}
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).
答案 0 :(得分:1)
如果序列号的低32位(在ESP标头中传输的部分)低于bottom
,则假定序列号子空间已移动(即高32位已增加)。 section A2.2. of RFC 4303涵盖了这一点:
Under Case A (Figure 1):
If Seql >= Bl (where Bl = Tl - W + 1), then Seqh = Th
If Seql < Bl (where Bl = Tl - W + 1), then Seqh = Th + 1
在section A2.3.(Else
块的If (Seql >= Tl - W + 1)
语句的If (Tl >= W - 1)
块)中显示了处理此伪代码的方法。在内核代码中,您在xfrm_replay_seqhi
中看到了类似的内容。
在检查序列号之后,使用完整的64位序列号(如果接收到的序列号在窗口以下,则高32位增加1)来验证数据包的完整性。如果失败,则数据包将被丢弃,否则窗口将被移动(xfrm_replay_advance_esn
),并且现在可能跨越两个子空间(RFC中的情况B)。