Subject: [TLS] Improved nonce generation method for TLS 1.3

From: Andrey Jivsov <[email-masked]>
Date: Fri, 2 Jun 2017 15:33:46 -0700

Greetings.

I would like to suggest a small tweak to the nonce generation method in
TLS 1.3.

The motivation for this is stronger separation between the encryption
layer and the TLS layer. An alignment with FIPS 140 guidance is another
motivation, which tells that the IV management shall be internal (in
encryption direction).

I realize that what I propose is a small tweak, and consequently, it
provides small benefits. One can take any side here. My view is that we
should try to clean things up, when possible.

Instead of requiring the understanding of the record numbers, the
encryption layer simply increments the initial nonce, which is a 12-byte
quantity for AES-GCM. The TLS layer passes in client_write_iv or
server_write_iv, along with the key, once per session, and the
encryption layer does ++ on nonce for each record from that point.

The method can be described as a counter mode with a random start.

There is one caveat. In order to maintain protocol version independence
we want to inhibit carry into the higher bytes (4 high bytes for
AES-GCM). This is behavior is standardized by
https://tools.ietf.org/html/rfc5116 and applies to TLS 1.2.

The benefits are that the encryption layer doesn't need to deal with a
record number or its serialization, or the mask. The state is minimal.
The nonce update code is faster and smaller (e.g. 3 instructions on x86_64).

I would like to thank earlier reviewers. As part of these reviews
RFC7905 was brought up. I appreciate the desire not to update the
RFC7905, but this should not interfere with the WGLC, and it's a fairly
new stream cipher anyway.

Details are in https://github.com/tlswg/tls13-spec/pull/1027

Thank you.

---

From: Adam Langley <[email-masked]>
Date: Fri, 2 Jun 2017 16:20:58 -0700

> new stream cipher anyway.

If the encryption layer implements the standard interface[1] then it
doesn't care about any of this anyway. Also, I'm not sure that it is any
faster (the current scheme can be done in three x86-64 instructions
too[2]), but any difference would be immeasurably tiny compared to the work
of the AEAD itself.

The overriding interest here is to avoid having yet another nonce format.
RFC 7905 diverged from TLS 1.2 with the intent that it would align with TLS
1.3. There would have to be a significant reason to add more complexity.

[1] https://tools.ietf.org/html/rfc5116#section-2.1
[2] context struct addr in rax, seq number in rcx: leaq maskOffset(%rax),
%rbx ; xorq (%rbx), %rcx ; movbeq %rcx, 4(%rdi)

Cheers

AGL

-- 
Adam Langley [email-masked] https://www.imperialviolet.org

---

From: Eric Rescorla <[email-masked]>
Date: Fri, 2 Jun 2017 16:25:28 -0700

It's worth noting that we considered a variant of this design initially
and then decided on the XOR design instead.

-Ekr

On Fri, Jun 2, 2017 at 4:20 PM, Adam Langley <[email-masked]> wrote:

> _______________________________________________
> TLS mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tls
>
>

---

From: Andrey Jivsov <[email-masked]>
Date: Fri, 2 Jun 2017 16:44:39 -0700

Regarding [2], we should be counting the functionality for serialization
and the increment of record number needed by the current nonce method.

Serialization would need two bswaps for little-endian platforms and an
increment. (We need to bring the integer into host format first, thus
the roundtrip with swaps.)

These are the 3 instructions that I counted: two bswaps, one increment.
That's all that my method needs.

If we assume that the layers are mixed together, there may be some reuse.

If we consider a stronger separation, where the encryption layer is as
independent as possible, it will have to do what the current TLS 1.3
prescribes independently.

I am not saying that performance savings due to this proposal are
significant. However, some may do encryption in hardware, while the
nonce will probably always be in software. My main point here is
simplicity. It seems easier to me to increment 12 bytes (suppressing the
carry) in-place.

On 06/02/2017 04:20 PM, Adam Langley wrote:
> On Fri, Jun 2, 2017 at 3:33 PM, Andrey Jivsov <[email-masked]
> <mailto:[email-masked]>> wrote:
> 
> too[2]), but any difference would be immeasurably tiny compared to the
> work of the AEAD itself.
> 
> The overriding interest here is to avoid having yet another nonce
> format. RFC 7905 diverged from TLS 1.2 with the intent that it would
> align with TLS 1.3. There would have to be a significant reason to add
> more complexity.
> 
> [2] context struct addr in rax, seq number in rcx: leaq
> maskOffset(%rax), %rbx ; xorq (%rbx), %rcx ; movbeq %rcx, 4(%rdi)
> 
> 
> Cheers
> 
> AGL
> 
> -- 
> Adam Langley [email-masked] <mailto:[email-masked]>
> https://www.imperialviolet.org

---

From: Nico Williams <[email-masked]>
Date: Fri, 2 Jun 2017 18:54:39 -0500

> motivation, which tells that the IV management shall be internal (in

FIPS-140 may have to align with TLS 1.3.  That's always an option.