summaryrefslogtreecommitdiffstats
path: root/src/vnet/ipsec/ah_decrypt.c
diff options
context:
space:
mode:
authorNeale Ranns <neale@graphiant.com>2021-06-28 13:31:28 +0000
committerBeno�t Ganne <bganne@cisco.com>2021-06-29 17:12:28 +0000
commit5b8911020ee5512d76c8daccaa199878ed7cbc01 (patch)
tree0c0960f5ffc12f1fe3d1a354a0736bd9ac374a07 /src/vnet/ipsec/ah_decrypt.c
parent3871bd3a07dfc775c29ea333d10c05ced2fea80e (diff)
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
Diffstat (limited to 'src/vnet/ipsec/ah_decrypt.c')
-rw-r--r--src/vnet/ipsec/ah_decrypt.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/src/vnet/ipsec/ah_decrypt.c b/src/vnet/ipsec/ah_decrypt.c
index d192fb6b80a..182ed3d231c 100644
--- a/src/vnet/ipsec/ah_decrypt.c
+++ b/src/vnet/ipsec/ah_decrypt.c
@@ -98,6 +98,7 @@ typedef struct
};
u32 sa_index;
u32 seq;
+ u32 seq_hi;
u8 icv_padding_len;
u8 icv_size;
u8 ip_hdr_size;
@@ -221,7 +222,8 @@ ah_decrypt_inline (vlib_main_t * vm,
pd->seq = clib_host_to_net_u32 (ah0->seq_no);
/* anti-replay check */
- if (ipsec_sa_anti_replay_check (sa0, pd->seq))
+ if (ipsec_sa_anti_replay_and_sn_advance (sa0, pd->seq, ~0, false,
+ &pd->seq_hi))
{
b[0]->error = node->errors[AH_DECRYPT_ERROR_REPLAY];
next[0] = AH_DECRYPT_NEXT_DROP;
@@ -257,7 +259,7 @@ ah_decrypt_inline (vlib_main_t * vm,
op->user_data = b - bufs;
if (ipsec_sa_is_set_USE_ESN (sa0))
{
- u32 seq_hi = clib_host_to_net_u32 (sa0->seq_hi);
+ u32 seq_hi = clib_host_to_net_u32 (pd->seq_hi);
op->len += sizeof (seq_hi);
clib_memcpy (op->src + b[0]->current_length, &seq_hi,
@@ -322,13 +324,14 @@ ah_decrypt_inline (vlib_main_t * vm,
if (PREDICT_TRUE (sa0->integ_alg != IPSEC_INTEG_ALG_NONE))
{
/* redo the anit-reply check. see esp_decrypt for details */
- if (ipsec_sa_anti_replay_check (sa0, pd->seq))
+ if (ipsec_sa_anti_replay_and_sn_advance (sa0, pd->seq, pd->seq_hi,
+ true, NULL))
{
b[0]->error = node->errors[AH_DECRYPT_ERROR_REPLAY];
next[0] = AH_DECRYPT_NEXT_DROP;
goto trace;
}
- ipsec_sa_anti_replay_advance (sa0, pd->seq);
+ ipsec_sa_anti_replay_advance (sa0, pd->seq, pd->seq_hi);
}
u16 ah_hdr_len = sizeof (ah_header_t) + pd->icv_size