From: Sabrina Dubroca <sd@queasysnail.net>
To: "Jérémy Jean" <jeremy.jean@oss.cyber.gouv.fr>
Cc: Steffen Klassert <steffen.klassert@secunet.com>,
Herbert Xu <herbert@gondor.apana.org.au>,
"David S. Miller" <davem@davemloft.net>,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] xfrm: esp6: fix off-by-one IV counter causing AES-GCM nonce reuse
Date: Tue, 29 Sep 2026 01:48:23 +0200 [thread overview]
Message-ID: <arr8x3a9Vqkg-ooM@krikkit> (raw)
In-Reply-To: <c443bad568f4e03d05b848b1b245707d@oss.cyber.gouv.fr>
2026-09-28, 21:33:41 +0200, Jérémy Jean wrote:
> On 2026-09-28 18:19, Sabrina Dubroca wrote:
> > 2026-09-25, 09:51:06 +0000, Jérémy Jean wrote:
> > > An off-by-one error in esp6_xmit() advances the IV counter before
> > > encrypting each software-GSO segment. For N segments with sequence
> > > numbers X through X+N-1, the IV counters are therefore X+1 through
> > > X+N.
> > > The following non-GSO packet uses X+N for both its sequence number and
> > > IV counter, repeating the last segment's AES-GCM nonce under the same
> > > key.
> >
> > I find this description very unclear. All I'm managing to understand
> > from this is "there's some situation where a packet isn't getting the
> > seqno it should". I don't know where the "+1" comes from since for GSO
> > the function does +N (xo->seq.low += skb_shinfo(skb)->gso_segs).
>
> I tried to be as explicit as possible, but I apologize if it was not
> good enough. My understanding on the full GSO processing isn't as
> deep as yours, so here is another try at explaining.
>
> The bug happens after software segmentation in GSO. When a large
> amount of data needs to span across several packets, software
> segmentation splits it into N smaller skb. After this split, each
> smaller skb holding the individual packets has skb_is_gso(skb)
> returning false, yet each skb keeps the flag XFRM_GSO_SEGMENT stating
> that this skb resulted from a segmentation. Consequently, the skb
> goes through the increment below in esp6_xmit():
>
> net/ipv6/esp6_offload.c:
> 355 if (xo->flags & XFRM_GSO_SEGMENT) {
> 356 esp.esph->seq_no = htonl(seq);
> 357
> 358 if (!skb_is_gso(skb))
> 359 xo->seq.low++; // <<< increment here
> 360 else
> 361 xo->seq.low += skb_shinfo(skb)->gso_segs;
> 362 }
>
> There are N calls to esp6_xmit() for all the smaller packets, and for
> each of them, the current sequence number is first written into the
> header, and then the shared counter for the next packet is
> incremented. However, the value esp.seqno used to construct the IV is
> derived from the counter value _after_ the increment.
Ok, I see now. One call to validate_xmit_xfrm() that calls
skb_gso_segment() and feeds those N non-GSO skbs to ->xmit one by one.
In that case, the seqno used in the IV wouldn't match the one that the
peer will reconstruct using the bottom 32b of seqno present in the
header, and it would never manage to decrypt anything we sent.
But luckily, it seems commenting out the memcpy(iv, seqno) line has no
effect (I think that's because all algorithms rely on either seqiv or
echainiv).
> For example, if
> the last packet produced by segmentation has sequence number 100, the
> IV is constructed using counter value 101. Then, a subsequent
> ordinary packet not going through segmentation is allocated sequence
> number 101, yet since it does not have the flag XFRM_GSO_SEGMENT,
> there is no increment, and its value is constructed from value 101 as
> well. Hence the nonce repetition.
I don't think that happens? The other packet will go through ->xmit
too and use the wrong seqno too.
--
Sabrina
next prev parent reply other threads:[~2026-09-28 23:48 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-25 9:51 Jérémy Jean
2026-09-28 16:19 ` Sabrina Dubroca
2026-09-28 19:33 ` Jérémy Jean
2026-09-28 23:48 ` Sabrina Dubroca [this message]
2026-09-29 9:47 ` Jérémy Jean
2026-09-29 13:00 ` Sabrina Dubroca
2026-09-29 13:13 ` Jérémy Jean
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=arr8x3a9Vqkg-ooM@krikkit \
--to=sd@queasysnail.net \
--cc=davem@davemloft.net \
--cc=herbert@gondor.apana.org.au \
--cc=jeremy.jean@oss.cyber.gouv.fr \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=steffen.klassert@secunet.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®