KDF API review, round 2

Michael StJohns mstjohns at comcast.net
Wed Nov 29 17:06:23 UTC 2017


Hi Jamil et al -

I think I finally understand the disconnect here - let me try and work 
through an explanation from another direction.

The TLS 1.3 KDF is NOT HKDF-Expand, it is HKDF-Expand-Label.

HKDF-Expand has a calling sequence of HKDF-Expand (Secret, Label, 
Length).   That results in underlying calls to T(n) = PRF (Secret, 
T(n-1) || label || n) for each block of key stream (RFC 5869 - page 3).

Two key things to understand here are:  that the Length value in 
HKDF-Expand is not passed in as a mixin, only as a value to determine 
how much key stream to produce; that the "label" parameter is just 
opaque data (remember this please - its important later).

HKDF-Expand-Label (Secret, Label, HashValue, Length)  is defined as 
HKDF-Expand (Secret, hkdfLabel, Length) where hkdfLabel is a structured 
value (NON-Opaque) consisting of the Length, Label (from the top level 
call) and Hash Value (also from the top level call) (TLS 1.3 section 7.1 
Key Schedule). The hkdfLabel ultimately is the "label" part of the call 
to the PRF.

A module creating a key from HKDF-Expand-Label knows that it MUST cut 
off the key stream after Length bytes (and if a new length value is 
provided, you get a whole different key stream).  It can read the 
hkdfLabel  from the call and know this production is for a key or an iv 
and set protections appropriately. HKDF-Expand-Label also knows that it 
will only produce a single object from each call.  In HDKF-Expand, the 
Label value is opaque.  It may contain the Length value, it may contain 
key tagging information, it may contain your dog's name, but since it's 
not structured in any way, an implementer of the HKDF-Expand calling 
convention can't do anything useful with that data in figuring out the 
assignment of the key stream to a key object.

I think what we have is a failure of language.  HKDF (and for that 
matter SP800-108) should be called key stream producers - not key 
derivation functions.  Mainly because they don't properly consider the 
assignment of the key stream bytes to the keys and how that interacts 
with the key stream production.

I need a way of making sure that 1) the key assignment/production 
specifications can be included in the mixins, and 2) a way of letting 
the module/provider be able to rely upon those specifications (e.g. by 
changing the key stream if the specifications change).  That means that 
the KeyDerivation calling convention needs to let me provide all of this 
data before the first call to derive a key.

This would have been more obvious had TLS1.3 kept the same multiple 
production per KDF call as was in previous versions - the HkdfLabel 
argument would have been an array of hkdfLabel structures.  They opted 
to clean it up slightly and limit it to a single production per KDF call.

Mike







More information about the security-dev mailing list