Previous Page
Next Page

11.3. Sequence Numbers

We've seen many times that in order to prevent replay attacks, a VPN should use sequence numbers in its packets. These sequence numbers can be explicit, as they are with AH, or implicit, as they are with SSHv2.

Recall that with SSHv2, the current sequence number is an input to the HMAC calculation, but the sequence number itself is not sent.

AH and SSHv2 present two very different environments in which to implement sequence numbering. In SSHv2, the notion of sequence numbers is natural because SSH uses TCP to carry its messages, and TCP guarantees that it will either deliver all the packets in order or terminate the connection. Thus, SSHv2 need merely check that each message has the expected sequence number. An erroneous sequence number in SSHv2 is an indication of an error or an attack, so SSH will terminate the session.

Notice how much more difficult checking sequence numbers is for AH. Because AH operates at the (best-effort) network layer, there is no guarantee that a datagram, and therefore the AH header, won't be dropped, delivered out of order, or duplicated. Thus, it's not sufficient for AH to remember the next expected sequence number and to check that an incoming datagram's sequence number matches it. When a datagram arrives, its sequence number can be

  1. Greater than the largest sequence number received

  2. Less than the largest sequence number received but not a duplicate of a previous sequence number

  3. Equal to a previously received sequence number

Ideally, we would like to accept datagrams in cases 1 and 2, and drop datagrams in case 3. In principle, we could do this by remembering each sequence number that we receive, but such a plan is obviously impractical, considering that the AH sequence number space is 232 - 1 numbers long. Instead, IPsec uses the idea of the antireplay window, introduced in Chapter 8.

If we look at the three cases again, we see that the real issue is determining whether a packet is a duplicate. Remembering every sequence number received would allow AH to check for duplicates but is not practical. The antireplay-window idea refines the idea of remembering all the sequence numbers to remembering whether the last n sequence numbers were received.

Figure 11.3 shows an example of this with n = 4, that is, with a window width of four sequence numbers. The figure shows that the largest sequence number received was 35 and that AH has remembered the state of sequence numbers 32 through 35.

Figure 11.3. A Sequence Number Antireplay Window


Note that 35 is not necessarily the last sequence number receivedthat might have been 33merely the largest.

We see that sequence numbers 32 and 34 have not yet been received but that sequence numbers 33 and 35 have been.

Now let's consider how AH can use the antireplay window to decide whether to accept a datagram. AH uses three rules to make its decision. The first rule is to reject any datagrams with sequence numbers to the left of the window. Thus, even though sequence number 30 has not yet been received, it will be rejected if it is received, because it lies to the left of the window, and AH has forgotten its state.

The second rule covers sequence numbers that fall within the window. This rule is to accept a sequence number in the window if the sequence number is marked as not yet received (0 in Figure 11.3) and to reject it otherwise. Thus, sequence numbers 32 and 34 would be accepted, but sequence numbers 33 or 35 would be rejected. If a sequence number is accepted by the second rule, it is marked as received so that it won't be accepted a second time.

RFC 2402 specifies that the window should be updated only if the packet also passes the integrity check. This ensures that a forged datagram with a bad authentication value will not force the rejection of a subsequent legitimate datagram with the same sequence number.

Finally, the third rule covers the case in which a datagram is received with a sequence number to the right of the window. Obviously, any sequence number to the right of the window has not yet been seen, so it should be accepted. Figure 11.4 shows what happens if sequence number 37 is received when the antireplay window looks like Figure 11.3.

Figure 11.4. The Antireplay Window Slides Right


The antireplay window has slid two sequence numbers to the right so that the new sequence number (37) is at the right-hand edge. Sequence number 32 is now to the left of the window and will never be accepted, even if it's received later. Sequence number 34, on the other hand, is still in the window and will be accepted if it's received before the window moves again.

RFC 2402 specifies that the antireplay window must be at least 32 sequence numbers wide and recommends that it be 64. With the recommended width, AH can remember the state of the previous 64 sequence numbers, which will generally be enough to account for any packet that is actually going to arrive.

Notice that it is critically important that the sequence numbers not be allowed to wrap. If they do, an old datagram with sequence number n could be substituted for the current datagram with the same sequence number, thus effecting a replay attack. Therefore, when the sequence number is about to wrap to 0, a new set of SAs is negotiated. Because the new SAs will have a different SPI and, except in manual keying, a new authentication key, any previous datagram that is replayed will be rejected even if it has a legal sequence number.


Previous Page
Next Page