QUIC: fixed computation of nonce

Roman Arutyunyan arut at nginx.com
Thu Nov 24 15:33:51 UTC 2022


Hi,

On Tue, Nov 22, 2022 at 02:29:47PM +0400, Sergey Kandaurov wrote:
> 
> > On 18 Nov 2022, at 20:48, Yu Zhu <yolkking at 126.com> wrote:
> > 
> > # HG changeset patch
> > # User Yu Zhu <lishu.zy at alibaba-inc.com>
> > # Date 1668789115 -28800
> > #      Sat Nov 19 00:31:55 2022 +0800
> > # Branch quic
> > # Node ID 1a320805265db14904ca9deaae8330f4979619ce
> > # Parent  6cf8ed15fd00668b7efa0226c06f47d7238f26e8
> > QUIC: fixed computation of nonce
> > 
> > RFC 9001, 5.3. AEAD Usage
> > The nonce, N, is formed by combining the packet protection IV with the packet number. The 62 bits of the reconstructed QUIC packet number in network byte order are left-padded with zeros to the size of the IV. The exclusive OR of the padded packet number and the IV forms the AEAD nonce.
> 
> While citing RFCs is certainly good, I would limit this
> to a specific description what this patch intends to do.
> 
> > 
> > diff -r 6cf8ed15fd00 -r 1a320805265d src/event/quic/ngx_event_quic_protection.c
> > --- a/src/event/quic/ngx_event_quic_protection.c        Tue Nov 01 17:00:35 2022 +0400
> > +++ b/src/event/quic/ngx_event_quic_protection.c        Sat Nov 19 00:31:55 2022 +0800
> > @@ -969,10 +969,11 @@
> >  static void
> >  ngx_quic_compute_nonce(u_char *nonce, size_t len, uint64_t pn)
> >  {
> > -    nonce[len - 4] ^= (pn & 0xff000000) >> 24;
> > -    nonce[len - 3] ^= (pn & 0x00ff0000) >> 16;
> > -    nonce[len - 2] ^= (pn & 0x0000ff00) >> 8;
> > -    nonce[len - 1] ^= (pn & 0x000000ff);
> > +    size_t  i;
> > +
> > +    for (i = 0; i < 8; i++) {
> > +        nonce[len - 8 + i] ^= (pn >> (8 - i - 1) * 8) & 0xff;
> > +    }
> >  }
> 
> Thanks for the patch.
> I tend to prefer computation with unrolled loops, though.
> Microbenchmarking shows that it performs better.
> Also, this allows to peel two high bits without additional branching.
> 
> 100m loop, user time in seconds
> 
>                 -O0     -O1     -O2
> gcc12/arm64
> old             0.609   0.233   0.024
> new             1.030   0.454   0.683
> clang14/arm64
> old             0.447   0.256   0.096*
> new             1.292   0.453   0.096*
> gcc8/i386
> old             1.519   0.541   0.551
> new             2.915   1.318   1.476
> 
> # HG changeset patch
> # User Sergey Kandaurov <pluknet at nginx.com>
> # Date 1669112795 -14400
> #      Tue Nov 22 14:26:35 2022 +0400
> # Branch quic
> # Node ID 29d8d12b6d35eb172465db2dff47bd8e98b36fc7
> # Parent  0f5fc7a320db621da8731a8832f486c7167b236b
> QUIC: fixed computation of nonce with packet numbers beyond 2^32.
> 
> Prodded by Yu Zhu.
> 
> diff --git a/src/event/quic/ngx_event_quic_protection.c b/src/event/quic/ngx_event_quic_protection.c
> --- a/src/event/quic/ngx_event_quic_protection.c
> +++ b/src/event/quic/ngx_event_quic_protection.c
> @@ -969,10 +969,14 @@ ngx_quic_parse_pn(u_char **pos, ngx_int_
>  static void
>  ngx_quic_compute_nonce(u_char *nonce, size_t len, uint64_t pn)
>  {
> -    nonce[len - 4] ^= (pn & 0xff000000) >> 24;
> -    nonce[len - 3] ^= (pn & 0x00ff0000) >> 16;
> -    nonce[len - 2] ^= (pn & 0x0000ff00) >> 8;
> -    nonce[len - 1] ^= (pn & 0x000000ff);
> +    nonce[len - 8] ^= (pn >> 56) & 0x3f;
> +    nonce[len - 7] ^= (pn >> 48) & 0xff;
> +    nonce[len - 6] ^= (pn >> 40) & 0xff;
> +    nonce[len - 5] ^= (pn >> 32) & 0xff;
> +    nonce[len - 4] ^= (pn >> 24) & 0xff;
> +    nonce[len - 3] ^= (pn >> 16) & 0xff;
> +    nonce[len - 2] ^= (pn >> 8) & 0xff;
> +    nonce[len - 1] ^= pn & 0xff;
>  }

Looks ok

--
Roman Arutyunyan



More information about the nginx-devel mailing list