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