B2. Anti-Replay Window (防重放窗口)
接收方将维护大小为 W 的防重放窗口。此窗口将限制数据包相对于到目前为止已认证的具有最高序列号的数据包可以有多大的乱序。(除了已为 32 位序列号窗口建立的 32 和 64 数据包值之外, 没有为此窗口的最小或推荐大小建立要求。但是, 建议实现者根据使用 ESN 选项的实现支持的接口速度来扩展这些值。此外, 下面描述的算法假设窗口宽度不超过 2^31 个数据包。) 与高 32 位 (Seqh) 的任何固定值关联的所有 2^32 个序列号以后将称为序列号子空间 (sequence number subspace)。下表列出了相关变量及其定义。
| Var. Name | Size (bits) | Meaning |
|---|---|---|
| W | 32 | Size of window (窗口大小) |
| T | 64 | Highest sequence number authenticated so far, upper bound of window (到目前为止已认证的最高序列号, 窗口上界) |
| Tl | 32 | Lower 32 bits of T (T 的低 32 位) |
| Th | 32 | Upper 32 bits of T (T 的高 32 位) |
| B | 64 | Lower bound of window (窗口下界) |
| Bl | 32 | Lower 32 bits of B (B 的低 32 位) |
| Bh | 32 | Upper 32 bits of B (B 的高 32 位) |
| Seq | 64 | Sequence Number of received packet (接收数据包的序列号) |
| Seql | 32 | Lower 32 bits of Seq (Seq 的低 32 位) |
| Seqh | 32 | Upper 32 bits of Seq (Seq 的高 32 位) |
在执行防重放检查或确定使用哪些高位来认证传入数据包时, 有两种情况:
- Case A (情况 A): Tl >= (W - 1)。在这种情况下, 窗口在一个序列号子空间内。(见图 1)
- Case B (情况 B): Tl < (W - 1)。在这种情况下, 窗口跨越两个序列号子空间。(见图 2)
在下面的图中, 底线 ("----") 显示了两个连续的序列号子空间, 零表示每个子空间的开始。它上面的两条较短的线显示了适用的高位。"====" 表示窗口。"****" 表示未来的序列号, 即超出当前已认证的最高序列号 (ThTl) 的序列号。
Th+1 *********
Th =======*****
--0--------+-----+-----0--------+-----------0--
Bl Tl Bl
(Bl+2^32) mod 2^32
Figure 1 -- Case A
Th ====**************
Th-1 ===
--0-----------------+--0--+--------------+--0--
Bl Tl Bl
(Bl+2^32) mod 2^32
Figure 2 -- Case B
B2.1. Managing and Using the Anti-Replay Window (管理和使用防重放窗口)
防重放窗口可以被认为是一串比特, 其中 'W' 定义了字符串的长度。W = T - B + 1, 值不能超过 2^32 - 1。最低位对应于 B, 最高位对应于 T, 从 Bl 到 Tl 的每个序列号都由相应的位表示。该位的值指示是否已接收和认证具有该序列号的数据包, 以便可以检测和拒绝重放。
当接收到具有大于 T 的 64 位序列号 (Seq) 的数据包并验证时,
- B 增加 (Seq - T)
- 从窗口的低端删除 (Seq - T) 位
- 在窗口的高端添加 (Seq - T) 位
- 设置顶部位以指示已接收和认证具有该序列号的数据包
- 设置 T 和顶部位之间的新位以指示尚未接收具有这些序列号的数据包。
- T 设置为新的序列号
在检查重放数据包时,
-
在情况 A 下: 如果 Seql >= Bl (其中 Bl = Tl - W + 1) 并且 Seql <= Tl, 则检查窗口中相应的位以查看此 Seql 是否已经被看到。如果是, 拒绝数据包。如果否, 执行完整性检查 (有关 SeqH 的确定, 请参阅下面的附录 B2.2)。
-
在情况 B 下: 如果 Seql >= Bl (其中 Bl = Tl - W + 1) 或 Seql <= Tl, 则检查窗口中相应的位以查看此 Seql 是否已经被看到。如果是, 拒绝数据包。如果否, 执行完整性检查 (有关 Seqh 的确定, 请参阅下面的附录 B2.2)。
B2.2. Determining the Higher-Order Bits (Seqh) of the Sequence Number (确定序列号的高位 (Seqh))
因为只有 'Seql' 将与数据包一起传输, 接收方必须推断和跟踪每个数据包所属的序列号子空间, 即, 确定 Seqh 的值。以下等式定义了如何在 "正常" 条件下选择 Seqh; 有关如何从极端数据包丢失中恢复的讨论, 请参阅附录 B3。
在情况 A 下 (图 1):
- 如果 Seql >= Bl (其中 Bl = Tl - W + 1), 则 Seqh = Th
- 如果 Seql < Bl (其中 Bl = Tl - W + 1), 则 Seqh = Th + 1
在情况 B 下 (图 2):
- 如果 Seql >= Bl (其中 Bl = Tl - W + 1), 则 Seqh = Th - 1
- 如果 Seql < Bl (其中 Bl = Tl - W + 1), 则 Seqh = Th
B2.3. Pseudo-Code Example (伪代码示例)
以下伪代码说明了上述防重放和完整性检查算法。'Seql', 'Tl', 'Th' 和 'W' 的值是 32 位无符号整数。算术是模 2^32。
If (Tl >= W - 1) Case A
If (Seql >= Tl - W + 1)
Seqh = Th
If (Seql <= Tl)
If (pass replay check)
If (pass integrity check)
Set bit corresponding to Seql
Pass the packet on
Else reject packet
Else reject packet
Else
If (pass integrity check)
Tl = Seql (shift bits)
Set bit corresponding to Seql
Pass the packet on
Else reject packet
Else
Seqh = Th + 1
If (pass integrity check)
Tl = Seql (shift bits)
Th = Th + 1
Set bit corresponding to Seql
Pass the packet on
Else reject packet
Else Case B
If (Seql >= Tl - W + 1)
Seqh = Th - 1
If (pass replay check)
If (pass integrity check)
Set the bit corresponding to Seql
Pass packet on
Else reject packet
Else reject packet
Else
Seqh = Th
If (Seql <= Tl)
If (pass replay check)
If (pass integrity check)
Set the bit corresponding to Seql
Pass packet on
Else reject packet
Else reject packet
Else
If (pass integrity check)
Tl = Seql (shift bits)
Set the bit corresponding to Seql
Pass packet on
Else reject packet