Thread (23 messages) 23 messages, 4 authors, 3d ago

Re: [PATCH ipsec 4/7] xfrm: prevent AES-GCM nonce reuse after early GSO

flat view

From: Jérémy Jean <hidden>
Date: 2026-10-01 21:07:58
Also in: stable

On 2026-10-01 15:31, Sabrina Dubroca wrote:
2026-09-30, 14:45:21 +0000, Jérémy Jean wrote:
quoted
In the software ESP offload path, xfrm_output_gso() leaves its segments
sharing a secpath extension. Each segment gets its own ESP sequence
number, but stores it in the same xo->seq field for IV generation.

If encryption is delayed, later segments overwrite the value needed by
earlier ones: esp*_xmit() can then encrypt several packets with the same
AES-GCM nonce, despite their distinct ESP sequence numbers.
Here again, your commit message could describe much more precisely
what actually happens.

I'm guessing you mean something that starts like

xfrm_output_gso
  segs = skb0,skb1... all with the same xo
  ...
  xfrm_output_one(skb0)
    xfrm_replay_overflow(skb0) xo->seq = N
  xfrm_output_one(skb1)
    xfrm_replay_overflow(skb1) xo->seq = N+1
  ...

[and then some more stuff happens that gives them the right
esph->seq_no but wrong 64b seqno used for the IV]

But please help reviewers trace the codepath you've already gone down,
without having to guess what you mean. You don't need to give the full
call graph with the state of each variable, but there needs to be more
than just the very beginning and the very end.
Here is a more verbose changelog I wrote for that patch:

---
With software ESP offload, xfrm_output() attaches a secpath before
calling xfrm_output_gso() for an encapsulated GSO packet, but
skb_gso_segment() leaves the splitted skbs sharing the same secpath,
including xo->seq.

For the i-th splitted segment, xfrm_output_gso() reaches
xfrm_replay_overflow() through xfrm_output_one(), which allocates
sequence number N+i to that segment, and then incorrectly overwrites
the shared xo->seq with N+i. If encryption is delayed until all t
segments have been processed, xo->seq ends up with value N+t-1 for all
segments. When validate_xmit_xfrm() calls esp*_xmit() for each
segment, the IV is constructed from the same value N+t-1, causing
nonce reuse in AES-GCM. Yet, each ESP header correctly keeps using
value N+i from its private XFRM_SKB_CB.

Call secpath_set() for each offloaded segment before xfrm_output2(),
so sequence allocation writes to private metadata that cannot be
overwritten by later segments.
---

Regards,
Jérémy
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help