Re: [TLS] Labels in the TLS 1.3 key schedule

Ilari Liusvaara <ilariliusvaara@welho.com> Tue, 10 October 2017 08:21 UTC

Return-Path: <ilariliusvaara@welho.com>
X-Original-To: tls@ietfa.amsl.com
Delivered-To: tls@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 79B89134A58 for <tls@ietfa.amsl.com>; Tue, 10 Oct 2017 01:21:43 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.9
X-Spam-Level:
X-Spam-Status: No, score=-1.9 tagged_above=-999 required=5 tests=[BAYES_00=-1.9] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id nNA5V8LzGpBF for <tls@ietfa.amsl.com>; Tue, 10 Oct 2017 01:21:41 -0700 (PDT)
Received: from welho-filter1.welho.com (welho-filter1.welho.com [83.102.41.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id E9B73134A19 for <tls@ietf.org>; Tue, 10 Oct 2017 01:21:40 -0700 (PDT)
Received: from localhost (localhost [127.0.0.1]) by welho-filter1.welho.com (Postfix) with ESMTP id B96A15371B; Tue, 10 Oct 2017 11:21:36 +0300 (EEST)
X-Virus-Scanned: Debian amavisd-new at pp.htv.fi
Received: from welho-smtp1.welho.com ([IPv6:::ffff:83.102.41.84]) by localhost (welho-filter1.welho.com [::ffff:83.102.41.23]) (amavisd-new, port 10024) with ESMTP id wS1FUsxkOGfF; Tue, 10 Oct 2017 11:21:35 +0300 (EEST)
Received: from LK-Perkele-VII (87-92-19-27.bb.dnainternet.fi [87.92.19.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by welho-smtp1.welho.com (Postfix) with ESMTPSA id 93E80C4; Tue, 10 Oct 2017 11:21:33 +0300 (EEST)
Date: Tue, 10 Oct 2017 11:21:33 +0300
From: Ilari Liusvaara <ilariliusvaara@welho.com>
To: Andrei Popov <Andrei.Popov@microsoft.com>
Cc: "<tls@ietf.org>" <tls@ietf.org>
Message-ID: <20171010082133.j4tk2epdijrfhawv@LK-Perkele-VII>
References: <CY4PR21MB012070DC2B0AD20603DBDD2F8C750@CY4PR21MB0120.namprd21.prod.outlook.com>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Disposition: inline
In-Reply-To: <CY4PR21MB012070DC2B0AD20603DBDD2F8C750@CY4PR21MB0120.namprd21.prod.outlook.com>
User-Agent: NeoMutt/20170609 (1.8.3)
Sender: ilariliusvaara@welho.com
Archived-At: <https://mailarchive.ietf.org/arch/msg/tls/xCTimys1C2icGM7I05d4CejMyxY>
Subject: Re: [TLS] Labels in the TLS 1.3 key schedule
X-BeenThere: tls@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: "This is the mailing list for the Transport Layer Security working group of the IETF." <tls.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/tls>, <mailto:tls-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/tls/>
List-Post: <mailto:tls@ietf.org>
List-Help: <mailto:tls-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/tls>, <mailto:tls-request@ietf.org?subject=subscribe>
X-List-Received-Date: Tue, 10 Oct 2017 08:21:43 -0000

On Tue, Oct 10, 2017 at 01:22:11AM +0000, Andrei Popov wrote:
> Sorry if I missed some text in the TLS 1.3 spec, but are the various
> labels used in the key schedule ASCII and nul-terminated?

The labels _are_ ASCII, but _not_ NUL-terminated. Instead, the labels
have explicit length field.


Constructing some examples of raw HKDF info blocks (for draft-21), I
hope these are correct:


Example 1) SHA-256, server handshake traffic secret:

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|00 20|12|ASCII(tls13 s hs traffic)             |
+--+--+--+     +--+--+--+--+--+--+--+--+--+--+--+
|              |20| Handshake hash up to and    |
+--+--+--+--+--+--+                             +
| including ServerHello                         |
+                 +--+--+--+--+--+--+--+--+--+--+
|                 |
+--+--+--+--+--+--+

Total 54 bytes, exactly fills one SHA-256 block after HKDF to HMAC
lowering and SHA-256 padding (not a coincidence). The byte immediately
before the boxed 0x20 contains ASCII 'c'.


Example 2) SHA-384 client application traffic secret:

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|00 30|12|ASCII(tls13 c ap traffic)             |
+--+--+--+     +--+--+--+--+--+--+--+--+--+--+--+
|              |30| Handshake hash up to and    |
+--+--+--+--+--+--+                             +
| including ServerFinished                      |
+                                               +
|                                               |
+                 +--+--+--+--+--+--+--+--+--+--+
|                 |
+--+--+--+--+--+--+

Total 70 bytes, fits into one SHA-384 compression, even after lowering
to HMAC and SHA-384 padding. The byte immediately before the boxed 0x30
contains ASCII 'c'.


Example 3) SHA-256, the "derived" stages (which are just before
injecting raw DHE result and just before injecting block of zeroes):

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|00 20|0d|ASCII(tls13 derived)                  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|20|e3 b0 c4 42 98 fc 1c 14 9a fb f4 c8 99 6f b9|
+--+                                            +
|24 27 ae 41 e4 64 9b 93 4c a4 95 99 1b 78 52 b8|
+  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|55|
+--+

Total of 49 bytes. Note e3...55 is SHA-256 of empty input. Another
place that uses similar construction is the per-exporter key
derivation. Byte 15, immedately before boxed 20 contains ASCII 'd'.


Example 4) SHA-384, traffic key update:

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|00 30|11|ASCII("tls13 traffic upd")            |
+--+--+--+  +--+--+--+--+--+--+--+--+--+--+--+--+
|           |00|
+--+--+--+--+--+

Total of 21 bytes. Note, no hash of empty input, as this uses
hkdf-expand-label as opposed to derive-secret. The byte immediately
before boxed 0x20 contains ASCII 'd'.


Example 5) SHA-256, inner exporter derivation for label
"EXPORTER: teap session key seed":

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|00 20|25|ASCII(tls13 EXPORTER: teap session key|
+--+--+--+                                      +
| seed)                                         |
+                       +--+--+--+--+--+--+--+--+
|                       |20|e3 b0 c4 42 98 fc 1c|
+--+--+--+--+--+--+--+--+--+                    +
|14 9a fb f4 c8 99 6f b9 24 27 ae 41 e4 64 9b 93|
+                          +--+--+--+--+--+--+--+
|4c a4 95 99 1b 78 52 b8 55|
+--+--+--+--+--+--+--+--+--+

Total of 73 bytes. Note, this blows SHA-256 block (this exporter inner
hash is the only place in current spec that might blow out SHA-256
block, However, if another hash function is defined, that might have
its block blown in other places too). The byte immedately before the
boxed 0x20 contains ASCII 'd'. Also note that the way the label is
split, there is a space between words "key" and "seed".

Without the empty hash, this would blow blocks less (e.g., would not
blow with this example label), but still could blow them, as the
maximum label is 249 bytes, giving 259+<hashoutputlen> byte raw info
block, which exceeds the blocksize of any known hash function).


Example 6) SHA-384, deriving IV for Chacha20-Poly1305:

+--+--+--+--+--+--+--+--+--+--+--+--+
|00 0c|08|ASCII(tls13 iv)        |00|
+--+--+--+--+--+--+--+--+--+--+--+--+

Total of 12 bytes (this is the shortest of these blocks). The output is
truncated to 12 bytes. The byte immedately before the boxed 0x00
contains ASCII 'v'.


Example 7) SHA-256, final exporter derivation step for 64-byte output
(exporter label is not material):

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|00 40|0E|ASCII(tls13 exporter)                 |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |00|
+--+--+

Note that HKDF lowers into HMAC two times here, since there is 33 to 64
bytes of output, but SHA-256 only produces 32 bytes of output. The
empty box in the last row contains ASCI 'r', as the label overflows to
byte 16.


-Ilari