QUIC: fixed computation of nonce

Sergey Kandaurov pluknet at nginx.com
Tue Nov 22 10:29:47 UTC 2022


> 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;
 }
 
 

-- 
Sergey Kandaurov



More information about the nginx-devel mailing list