Skip to content

Commit

Permalink
arch/checksum: fix bug in carry propagation
Browse files Browse the repository at this point in the history
This fixes a bug in our scalar x86 IP checksum implementation, where some
carries where missed. Really hard to find with random testing, added a
systematic test case for carry propagation.
  • Loading branch information
eugeneia committed Apr 17, 2020
1 parent 4b0c18b commit 0068df6
Showing 1 changed file with 10 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/arch/checksum.dasl
Original file line number Diff line number Diff line change
Expand Up @@ -71,20 +71,23 @@ local function gen_checksum ()
| jl >5 -- Jump to branch '3'.
| mov r9d, dword [rdi + r8] -- Fetch 32-bit from data + r8 into r9d.
| add rax, r9 -- Sum acc with r9. Accumulate carry.
| adc rax, 0 -- Sum carry-bit into acc.
| sub rcx, 4 -- Decrease index by 4.
| add r8, 4 -- Next 32-bit.
| 5:
| cmp rcx, 2 -- If index is less than 2.
| jl >6 -- Jump to branch '4'.
| movzx r9, word [rdi + r8] -- Fetch 16-bit from data + r8 into r9.
| add rax, r9 -- Sum acc with r9. Accumulate carry.
| adc rax, 0 -- Sum carry-bit into acc.
| sub rcx, 2 -- Decrease index by 2.
| add r8, 2 -- Next 16-bit.
| 6:
| cmp rcx, 1 -- If index is less than 1.
| jl >7 -- Jump to branch '5'.
| movzx r9, byte [rdi + r8] -- Fetch 8-bit from data + r8 into r9.
| add rax, r9 -- Sum acc with r9. Accumulate carry.
| adc rax, 0 -- Sum carry-bit into acc.
-- Fold 64-bit into 16-bit.
| 7:
| mov r9, rax -- Assign acc to r9.
Expand Down Expand Up @@ -157,4 +160,11 @@ function selftest ()
assert(hex(checksum(pkt.data, pkt.length, 0)) == hex(ntohs(checksum_lua(pkt.data, pkt.length))))
assert(hex(checksum(pkt.data, pkt.length, 0)) == hex(C.cksum_generic(pkt.data, pkt.length, 0)))
end
-- Test carry propagation
for l = 1, 63 do
local pkt = { data = ffi.new("uint8_t[?]", l), length = l }
for i = 0, l-2 do pkt.data[i]=0xff end; pkt.data[l-1] = 0x01
assert(hex(checksum(pkt.data, pkt.length, 0)) == hex(ntohs(checksum_lua(pkt.data, pkt.length))))
assert(hex(checksum(pkt.data, pkt.length, 0)) == hex(C.cksum_generic(pkt.data, pkt.length, 0)))
end
end

0 comments on commit 0068df6

Please sign in to comment.