KDF API review, round 2

Michael StJohns mstjohns at comcast.net
Fri Nov 17 15:04:05 UTC 2017


On 11/16/2017 2:15 PM, Adam Petcher wrote:
>
> On 11/16/2017 12:47 AM, Michael StJohns wrote:
>
>> This is pretty close, but I think you need to add an 
>> AlgorithmParameters argument to each of the getInstance calls in 
>> KeyDerivation - or require each KDF to specify a default model - not 
>> all KDFs are fully specified in a given document.
>>
>> Alternately, you could use the .setParameter/.getParameter model of 
>> signature,  but it may be that underlying code will actually be 
>> creating a whole new instance.  (E.g. getInstance("NIST-SP800-108") 
>> vs getInstance("NIST-SP800-108-Counter") vs 
>> getInstance("NIST-SP800-108/Counter"))
>>
>>
>> Here's the model I'm thinking about:
>>
>>     SP800-108 is a parameterized set of Key derivation functions
>>     which goes something like:
>>
>>         Pick either Counter or Feedback
>>
>>         Pick the PRF (e.g. HMAC-SHA256, AES-128-CMAC, etc)
>>         Pick the size of the counter and endianness:  (e.g. Big
>>         endian Uint16)
>>
>>         Pick the size and endianness of L
>>
>>         Pick whether the counter precedes or follows the fixed data
>>         (for counter mode).
>>         Pick whether the counter is included and whether it precedes
>>         or follows the fixed data (for feedback mode)
>>
>>
>> Taken together those instantiation parameters define a particular KDF 
>> model.
>>
>> Then for the .init() call, the kdfParams is where the Label and 
>> Context data go (what HKDF calls 'info').  For most KDFs this could 
>> just be a byte array.
>>
>> For HKDF the getInstance must specify an underlying hash function - 
>> by definition mode is feedback, the size of the counter is fixed, L 
>> is not included in the base calculation. (TLS1.3 uses HKDF and makes 
>> L a mandatory part of the HKDF).
>
> I don't like the idea of putting algorithm parameters in getInstance, 
> because we don't have this pattern in JCA, and it doesn't seem like it 
> is necessary here. 
Which is why I mentioned the Signature.setParameter() pattern as an 
alternative.

> In your example above, the first set of parameters are somehow 
> different from the second set, but it is not clear how.
The first set configures HOW the kdf operations, the second (.init()) 
gives the parameters needed for a specific set of invocations.
> So it seems like they could all be supplied to init. Alternatively, 
> algorithm names could specify more concrete algorithms that include 
> the mode/PRF/etc. Can you provide more information to explain why 
> these existing patterns won't work in this case?
What I need to do is provide a lifecycle diagram, but its hard to do in 
text.  But basically, the .getInstance() followed by .setParameters() 
builds a concrete engine while the .init() initializes that engine with 
a key and the derivation parameters. Think about a TLS 1.2 instance - 
the PRF is selected once, but the KDF may be used multiple times.

I considered the mode/PRF/etc stuff but that works for things like 
Cipher and Signature because most of those have exactly the same 
pattern.  For the KDF pattern we;ve got fully specified KDFs (e.g. TLS 
1.1 and before, IPSEC), almost fully specified KDFs (TLS 1.2 and HDKF 
needs a PRF) and then the SP800 style KDFs which are defined to be 
*very* flexible.  So translating that into a naming convention is going 
to be restrictive and may not cover all of the possible approaches.  I'd 
rather do it as an algorithmparameter instead. With a given KDF 
implementation having a default if nothing is specified during 
instantiation.

Mike




-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/security-dev/attachments/20171117/9f906cc7/attachment.htm>


More information about the security-dev mailing list