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

Reply via email to