Skip to content

Commit

Permalink
lib.ipsec.esp: More thourough testing of the anti-replay facilities
Browse files Browse the repository at this point in the history
  • Loading branch information
Timo Buhrmester committed Jul 26, 2016
1 parent 363b1bf commit 72532f6
Showing 1 changed file with 56 additions and 20 deletions.
76 changes: 56 additions & 20 deletions src/lib/ipsec/esp.lua
Expand Up @@ -193,9 +193,6 @@ ABCDEFGHIJKLMNOPQRSTUVWXYZ
assert(packet.length(p2) == packet.length(p)
and C.memcmp(p, p2, packet.length(p)) == 0,
"integrity check failed")
-- Check replayed packet XXX do this a lot more thoroughly
p2 = packet.clone(p_enc)
assert(not dec:decapsulate(p2), "replayed decapsulation succeeded")
-- Check invalid packets.
local p_invalid = packet.from_string("invalid")
assert(not enc:encapsulate(p_invalid), "encapsulated invalid packet")
Expand All @@ -218,27 +215,66 @@ ABCDEFGHIJKLMNOPQRSTUVWXYZ
and C.memcmp(p_min, e_min, packet.length(p_min)) == 0,
"integrity check failed")
-- Check transmitted Sequence Number wrap around
enc.seq:low(0)
enc.seq:high(1)
dec.seq:low(2^32 - dec.window_size)
dec.seq:high(0)
C.track_seq_no(dec.seq:high(), dec.seq:low(), dec.seq.no, dec.window, dec.window_size)
local p3 = packet.clone(p)
enc:encapsulate(p3)
assert(dec:decapsulate(p3),
C.memset(dec.window, 0, dec.window_size / 8); -- clear window
enc.seq.no = 2^32 - 1 -- so next encapsulated will be seq 2^32
dec.seq.no = 2^32 - 1 -- pretend to have seen 2^32-1
local px = packet.clone(p)
enc:encapsulate(px)
assert(dec:decapsulate(px),
"Transmitted Sequence Number wrap around failed.")
assert(dec.seq:high() == 1 and dec.seq:low() == 1,
assert(dec.seq:high() == 1 and dec.seq:low() == 0,
"Lost Sequence Number synchronization.")
-- Check Sequence Number exceeding window
enc.seq:low(0)
enc.seq:high(1)
dec.seq:low(dec.window_size+1)
dec.seq:high(1)
C.track_seq_no(dec.seq:high(), dec.seq:low(), dec.seq.no, dec.window, dec.window_size)
local p4 = packet.clone(p)
enc:encapsulate(p4)
assert(not dec:decapsulate(p4),
C.memset(dec.window, 0, dec.window_size / 8); -- clear window
enc.seq.no = 2^32
dec.seq.no = 2^32 + dec.window_size + 1
px = packet.clone(p)
enc:encapsulate(px)
assert(not dec:decapsulate(px),
"Accepted out of window Sequence Number.")
assert(dec.seq:high() == 1 and dec.seq:low() == dec.window_size+1,
"Corrupted Sequence Number.")
-- Test anti-replay: From a set of 15 packets, first send all those
-- that have an even sequence number. Then, send all 15. Verify that
-- in the 2nd run, packets with even sequence numbers are rejected while
-- the others are not.
-- Then do the same thing again, but with offset sequence numbers so that
-- we have a 32bit wraparound in the middle.
local offset = 0 -- close to 2^32 in the 2nd iteration
for offset = 0, 2^32-7, 2^32-7 do -- duh
C.memset(dec.window, 0, dec.window_size / 8); -- clear window
dec.seq.no = offset
for i = 1+offset, 15+offset do
if (i % 2 == 0) then
enc.seq.no = i-1 -- so next seq will be i
px = packet.clone(p)
enc:encapsulate(px);
assert(dec:decapsulate(px), "rejected legitimate packet seq=" .. i)
assert(dec.seq.no == i, "Lost sequence number synchronization")
end
end
for i = 1+offset, 15+offset do
enc.seq.no = i-1
px = packet.clone(p)
enc:encapsulate(px);
if (i % 2 == 0) then
assert(not dec:decapsulate(px), "accepted replayed packet seq=" .. i)
else
assert(dec:decapsulate(px), "rejected legitimate packet seq=" .. i)
end
end
end
-- Check that packets from way in the past/way in the future
-- (further than the biggest allowable window size) are rejected
-- This is where we ultimately want resynchronation (wrt. future packets)
C.memset(dec.window, 0, dec.window_size / 8); -- clear window
dec.seq.no = 2^34 + 42;
enc.seq.no = 2^36 + 42;
px = packet.clone(p)
enc:encapsulate(px);
assert(not dec:decapsulate(px), "accepted packet from way into the future")
enc.seq.no = 2^32 + 42;
px = packet.clone(p)
enc:encapsulate(px);
assert(not dec:decapsulate(px), "accepted packet from way into the past")
end

0 comments on commit 72532f6

Please sign in to comment.