QUIC: fixed computation of nonce

Sergey Kandaurov pluknet at nginx.com
Fri Nov 25 12:00:57 UTC 2022


> On 24 Nov 2022, at 19:33, Roman Arutyunyan <arut at nginx.com> wrote:
> 
> 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

https://hg.nginx.org/nginx-quic/rev/70ce1e927715

-- 
Sergey Kandaurov



More information about the nginx-devel mailing list