ipsec: Fix setting the hi-sequence number for decrypt
Type: fix
two problems;
1 - just because anti-reply is not enabled doesn't mean the high sequence
number should not be used.
- fix, there needs to be some means to detect a wrapped packet, so we
use a window size of 2^30.
2 - The SA object was used as a scratch pad for the high-sequence
number used during decryption. That means that once the batch has been
processed the high-sequence number used is lost. This means it is not
possible to distinguish this case:
if (seq < IPSEC_SA_ANTI_REPLAY_WINDOW_LOWER_BOUND (tl))
{
...
if (post_decrypt)
{
if (hi_seq_used == sa->seq_hi)
/* the high sequence number used to succesfully decrypt this
* packet is the same as the last-sequnence number of the SA.
* that means this packet did not cause a wrap.
* this packet is thus out of window and should be dropped */
return 1;
else
/* The packet decrypted with a different high sequence number
* to the SA, that means it is the wrap packet and should be
* accepted */
return 0;
}
- fix: don't use the SA as a scratch pad, use the 'packet_data' - the
same place that is used as the scratch pad for the low sequence number.
other consequences:
- An SA doesn't have seq and last_seq, it has only seq; the sequence
numnber of the last packet tx'd or rx'd.
- there's 64bits of space available on the SA's first cache line. move
the AES CTR mode IV there.
- test the ESN/AR combinations to catch the bugs this fixes. This
doubles the amount of tests, but without AR on they only run for 2
seconds. In the AR tests, the time taken to wait for packets that won't
arrive is dropped from 1 to 0.2 seconds thus reducing the runtime of
these tests from 10-15 to about 5 sceonds.
Signed-off-by: Neale Ranns <neale@graphiant.com>
Change-Id: Iaac78905289a272dc01930d70decd8109cf5e7a5
diff --git a/src/vnet/ipsec/esp.h b/src/vnet/ipsec/esp.h
index a0643c3..d179233 100644
--- a/src/vnet/ipsec/esp.h
+++ b/src/vnet/ipsec/esp.h
@@ -118,7 +118,8 @@
}
always_inline u16
-esp_aad_fill (u8 * data, const esp_header_t * esp, const ipsec_sa_t * sa)
+esp_aad_fill (u8 *data, const esp_header_t *esp, const ipsec_sa_t *sa,
+ u32 seq_hi)
{
esp_aead_t *aad;
@@ -128,7 +129,7 @@
if (ipsec_sa_is_set_USE_ESN (sa))
{
/* SPI, seq-hi, seq-low */
- aad->data[1] = (u32) clib_host_to_net_u32 (sa->seq_hi);
+ aad->data[1] = (u32) clib_host_to_net_u32 (seq_hi);
aad->data[2] = esp->seq;
return 12;
}
@@ -199,7 +200,7 @@
i16 current_length;
u16 hdr_sz;
u16 is_chain;
- u32 protect_index;
+ u32 seq_hi;
} esp_decrypt_packet_data_t;
STATIC_ASSERT_SIZEOF (esp_decrypt_packet_data_t, 3 * sizeof (u64));