Hi Juoni,
Thanks for taking the time. I suspect this will take a few iterations to get
the actual text right, as I am drinking water from a fire hose here. Please
bear with me.
> On 24 Nov 2019, at 12:31, Jouni Malinen <[email protected]> wrote:
>
> On Fri, Nov 22, 2019 at 05:21:10PM +0800, Eliot Lear wrote:
>> I have been reviewing this erratum, and I think it is correct, but I have a
>> question:
>>
>>> Section 5.2. says:
>>>
>>> IMSK = First 32 octets of TLS-PRF(EMSK, "[email protected]" |
>>> "\0" | 64)
>>> It should say:
>>>
>>> IMSK = First 32 octets of TLS-PRF(EMSK, "[email protected]" |
>>> "\0", 64)
>>
>> Is that last parameter “seed” or “seed size”? Confusedly yours.
>
> It's neither.. The main problem here is in RFC 7170 not defining
> TLS-PRF() properly. All it says is "TLS-PRF is the PRF negotiated as
> part of TLS handshake" while RFC 5246 does not define PRF as a function
> with arguments that would be compatible with even a single instance of
> TLS-PRF() use in RFC 7170..
> And the RFC 7170 uses are inconsistent with
> themselves like this erratum show, but this instance is not the only
> issue: TLS-PRF() is used with two, three, and even four arguments.
Indeed. So that we’re clear, here they are:
Section 5.2:
IMSK = First 32 octets of TLS-PRF(EMSK, "[email protected]" |
"\0" | 64)
2 args.
Later, same section:
IMCK[j] = TLS-PRF(S-IMCK[j-1], "Inner Methods Compound Keys",
IMSK[j], 60)
4 args.
And then further down:
MSK = TLS-PRF(S-IMCK[j], "Session Key Generating Function", 64)
EMSK = TLS-PRF(S-IMCK[j],
"Extended Session Key Generating Function", 64)
3 args.
And 5246 says:
PRF(secret, label, seed) = P_<hash>(secret, label + seed)
And so I agree with you that nowhere is there a length field for the return
value in RFC 5246.
> This
> leaves the implementer guessing what exactly these maps 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)"
>
> So this PRF(secret, label, seed) is what is available and RFC 5246 does
> not define that 64 part in the example above as an argument. That 64 is
> the number of octets of output that is fetched from the PRF.
>
> In other words, RFC 7170 should have defined TLS-PRF(secret, label,
> seed, output-len-in-octets) as taking output-len-in-octets of octets
> from the output of RFC 5246 PRF(secret, label, seed). With this,
> following fixes would be needed for the users for TLS-PRF() in RFC 7170:
>
> IMSK:
> This could be one of following (last two having identical outcome):
> TLS-PRF(EMSK, "[email protected] <mailto:[email protected]>", "", 64)
> TLS-PRF(EMSK, "[email protected] <mailto:[email protected]>", "\0", 64)
> TLS-PRF(EMSK, "[email protected] <mailto:[email protected]>", "\0" |
> 0x00 | 0x40, 64)
> TLS-PRF(EMSK, "[email protected] <mailto:[email protected]>", 0x00 |
> 0x00 | 0x40, 64)
>
> However, this TLS-PRF() instance is more strange.. The "Optional data
> parameter is not used in the derivation" part does not make any sense
> since I think "optional data parameter" is a reference to the seed value
> going into PRF.
Could it be that this text refers to RFC 5295:
> If an inner method supports export of an Extended Master Session Key
> (EMSK), then the IMSK SHOULD be derived from the EMSK as defined in
> [RFC5295]. The usage label used is "[email protected]", and the
> length is 64 octets. Optional data parameter is not used in the
> derivation.
USRK = KDF(EMSK, key label | "\0" | optional data | length)
Which perhaps is meant to translate to:
IMSK = KDF(EMSK, “[email protected] <mailto:[email protected]>”, 64)
But again, only when the inner method supports export of the EMSK. Note the
text below, by the way:
> USRKs MUST be at least 64 octets in length.
However we interpret the text, it seems that either the argument count is wrong
or the function is wrong.
> The following description is then clearly indicating
> that "\0" is 0x00 and length (that | 64) is "2-octet unsigned integer in
> network byte order". That seems to be talking about some binary data
> and the seed is the only place where such byte order and field size
> discussion would apply. I'm actually implementing that last one because
> of that discussion in the RFC.
>
> It should also be noted that the "First 32 octets of TLS-PRF(..., 64)"
> does not make much sense since "TLS-PRF(..., 32)" would cover same. This
> would seem to imply that "First 32 octets of TLS-PRF" could actually be
> trying to address that PRF argument mismatch. Anyway, maybe this should
> simply say:
>
> IMSK = TLS-PRF(EMSK, "[email protected] <mailto:[email protected]>",
> 0x00 | 0x00 | 0x40, 32)
> (or with empty seed "" instead of that 3 octet seed)
I’m really not sure what adding a known seed gets us at this point.
>
> The "and the length is 64 octets" part just above this is a bit
> confusing with this, though.
>
>
>
>
> IMCK[j] = TLS-PRF(S-IMCK[j-1], "Inner Methods Compound Keys", IMSK[j], 60)
> (this is actually unchanged)
>
> MSK = TLS-PRF(S-IMCK[j], "Session Key Generating Function", "", 64)
> (i.e., add the missing empty seed)
>
> EMSK = TLS-PRF(S-IMCK[j],
> "Extended Session Key Generating Function", "", 64)
> (i.e., add the missing empty seed)
On the last two, entropy is thus borrowed from S-IMCK[j]. Correct? I don’t
have the full flow in my head, but are these indepedently generated on both
sides, right? If so, I don’t see any other alternative to what you are
suggesting.
Eliot_______________________________________________
Emu mailing list
[email protected]
https://www.ietf.org/mailman/listinfo/emu