Subject: [Emu] Proposed resolution for TEAP errata 5127

From: Joseph Salowey <[email-masked]>
Date: Wed, 21 Oct 2020 09:30:33 -0700

Errata 5127: https://www.rfc-editor.org/errata/eid5127
Proposed State: Verified
Revision:
Section 5.2.
OLD

IMSK = First 32 octets of TLS-PRF(EMSK, "[email-masked]" |
     "\0" | 64)

NEW

IMSK = First 32 octets of TLS-PRF(EMSK, "[email-masked]" |
   '/0', 64)

Notes:
According to

RFC5246 The Transport Layer Security (TLS) Protocol Version 1.2

5. HMAC and the Pseudorandom Function

"TLS's PRF is created by applying P_hash to the secret as:

PRF(secret, label, seed) = P_<hash>(secret, label + seed)"

In this case the seed is the 2-byte length of the output as defined by RFC
5295.  In terms of P_<Hash> the derivation would look like:

IMSK = P_<Hash>(EMSK, "[email-masked]" | 0x00 | 0x00 | 0x40)

---

From: Jouni Malinen <[email-masked]>
Date: Wed, 21 Oct 2020 22:08:24 +0300

> IMSK = First 32 octets of TLS-PRF(EMSK, "[email-masked]" |

Why would this change "\0" to '/0'?

How is that 64 supposed to be encoded if it is the "seed" argument to
PRF(secret, label, seed) define in RFC 5246 Section 5?

> IMSK = P_<Hash>(EMSK, "[email-masked]" | 0x00 | 0x00 | 0x40)

Using P_hash(EMSK, "[email-masked]" | 0x00 | 0x00 | 0x40) looks
correct, but it looks strange to me if we are trying to include the
first 0x00 at the end of the "label" argument to PRF(secret, label,
seed) especially when the label is define to be "an ASCII string. It
should be included in the exact form it is given without a length byte
or trailing null character". I would have expected
"[email-masked]" to be the "label" while 0x00 | 0x00 | 0x40 would
be the "seed". In other words:

IMSK = First 32 octets of TLS-PRF(EMSK, "[email-masked]",
				  0x00 | 0x00 | 0x40).

Please note that this is followed by this explanation:

     where "|" denotes concatenation, EMSK is the EMSK from the inner
     method, "[email-masked]" consists the ASCII value for the
     label "[email-masked]" (without quotes), "\0" = is a NULL
     octet (0x00 in hex), length is the 2-octet unsigned integer in
     network byte order, and TLS-PRF is the PRF negotiated as part of
     TLS handshake [RFC5246].

Using "64" as the seed would require the reader to interpret 64 to be
the "length" and use the "2-octet unsigned integer in network byte
order" from that to determine the exact encoding of the seed. And the
first 0x00 as part of the label to TLS-PRF would be be confusing as well
with this explanation that is clearly defining the label without
including the explicitly noted "\0" after the label.

-- 
Jouni Malinen                                            PGP id EFC895FA

---

From: Joseph Salowey <[email-masked]>
Date: Wed, 21 Oct 2020 14:14:45 -0700

On Wed, Oct 21, 2020 at 12:11 PM Jouni Malinen <[email-masked]> wrote:

> [Joe] that was my mistake should be "/0"

> PRF(secret, label, seed) define in RFC 5246 Section 5?
[Joe] 7170 says "length is the 2-octet unsigned integer in network byte
order"

> IMSK = First 32 octets of TLS-PRF(EMSK, "[email-masked]",
[Joe] Yes I agree that is better how about this as the text change

IMSK = First 32 octets of TLS-PRF(EMSK, "[email-masked]", "\0" |  64)

---

From: Jouni Malinen <[email-masked]>
Date: Fri, 23 Oct 2020 19:08:15 +0300

> [Joe] 7170 says "length is the 2-octet unsigned integer in network byte

It does, but how would one know that this particular 64 is "length"?
This "64" argument is the "seed" argument to PRF and that could be any
arbitrary data.. The length of TLS-PRF output is meta data that is not
passed to the PSK() defined in RFC 5246 directly as an argument, i.e.,
inclusion of the output length in the seed is something that RFC 7170 is
doing here for some reason and it could have included any other
arbitrary seed value here for that matter.. IMHO, this is too vague and
it would be better to spell out the exact contents of the seed value
(0x00 | 0x40 im this particular case shown here or 0x00 | 0x00 | 0x40 if
following the proposal below).

> IMSK = First 32 octets of TLS-PRF(EMSK, "[email-masked]", "\0" |  64)

It looks quite strange to me to define a binary seed data as a
concatenation of a string and an integer. I have the exact same question
about the encoding of 64 here since this does not describe explicitly
this instance of 64 to be the "length" which has the particular encoding
described in RFC 7170. For me, using 0x00 | 0x00 | 0x40 and deleting
that note about length encoding would be significantly clearer. If that
is not acceptable, I would still replace "\0" with 0x00 in this context
since this is not an ASCII string or label anymore, but binary data. And
in addition to that, the "64" part would need to be replaced with
something like "TLS-PRF output length" and then the "TLS-PRF output
length" could be mentioned to be 64 in this instance and the encoding
for that would be 2-octet unsigned integer in network byte order.

---

From: Joseph Salowey <[email-masked]>
Date: Fri, 23 Oct 2020 12:26:53 -0700

> following the proposal below).
[Joe]  The length is called out as 64 octets in the sentence just before
this, to me this is not very vague.   However, I do agree that specifying
the exact encoding would be even clearer.  Here is a proposed revision that
I think addresses this and the comment later on in the message:

     0x00 | 0x00 | 0x40)

     where "|" denotes concatenation and the TLS-PRF is defined in
      [RFC5246] as

     PRF(secret, label, seed) = P_<hash>(secret, label | seed).

     the secret is the EMSK from the inner method, the label is
     "[email-masked]" consisting of the ASCII value for the
     label "[email-masked]" (without quotes),  the seed
     consists of the "\0" null delimiter (0x00) and 2-octet unsigned
     integer length in network byte order (0x00 | 0x4) specified
     in [RFC5295]