KDF API review, round 2

Jamil Nimeh jamil.j.nimeh at oracle.com
Mon Nov 20 22:33:34 UTC 2017



On 11/20/2017 12:34 PM, Michael StJohns wrote:
> On 11/20/2017 1:10 PM, Jamil Nimeh wrote:
>>
>>> You're missing the point that setParameter() provides information 
>>> used in all future calls to the signature generation, while init() 
>>> provides data specifically for a given key stream production.  In 
>>> Signature() you call .setParameter() to set up the PSS parameters 
>>> (or use the defaults).  Each subsequent call to initSign or 
>>> initVerify uses those PSS parameters.  The equivalent part of 
>>> .init() in KeyDerivation is actually the calls to .update() in 
>>> signature as they provide the specific information for the 
>>> production of the output key stream.  In fact, setting up an HMAC 
>>> signature instance and passing it the mixin data as part of a 
>>> .update() is a way of producing the key stream round.
>>>
>>> So equivalences:
>>>
>>> KeyDerivation.getInstance(PRF) == Signature.getInstance(HMAC)
>>> KeyDerivation.setParameters() == Signature.setParameters()
>>> KeyDerivation.init(key, List<Parameters>) == concatenation of the 
>>> results of multiple calls (each key stream round based on the needed 
>>> output length) to [Signature.initSign(Key) followed by 
>>> Signature.update(converttobytearray(List<Parameters>)) followed by  
>>> Signature.sign()] to produce the key stream
>>> KeyDerivation.deriveKey() ==  various calls to key or object 
>>> factories with parts of the key stream (signature).
>>>
>> Are you expecting that setParameters is called once per 
>> instantiation?  If so, then the parameters that would go into 
>> setParameter (an APS I assume) could just as easily go into the 
>> getInstance call.  It also removes the chance that someone would call 
>> it twice.
>
> That was my original proposal.  .setParameter() was an alternative 
> that matched the Signature pattern.
Yes, I recall that.  Since it's a once-per instance call let me come up 
with a rev with it in the getInstance.  There's precedent for 
getInstance with APS, too.  It's just not any of the keyed forms, and 
the rationale for that was to combine instantiation and initialization 
(CertStore is an example).  It's not a great comparison to KDF for a 
myriad of reasons most of which you've talked about...but it at least 
shows that we have added params to getInstance calls in the past.  This 
seems like one place where we're not going to come up with an answer 
that pleases everyone.
>>
>> If you're expecting someone to call setParameter more than once, then 
>> I would expect an init must follow.  So why not place it in a form of 
>> init that allows you to change that particular set of params?  Either 
>> way it seems like we could coalesce this method into one of the calls 
>> that sandwich it in your proposed model.
>>
>>
>
> I don't expect them to call it more than once.  The original (now 
> deprecated) .setParameter (String, Object) method in Signature 
> indicated it could be called only once and would throw an error if 
> called again - I'm not sure why that wasn't brought forward to the 
> Signature.setParameter(AlgorithmParameterSpec) method.
>
> In any event, I'd rather do the parameter setting in the getInstance 
> call than as a separate .setParameters call if it can be done without 
> exploding the interface.
>
> Hmm.. how does that map to the Spi?  Does the 
> KeyDerivation.getInstance() code instantiate the object, call a 
> setParameter() method on the SPI and then return the new object? Or 
> what?  It may make more sense to just add the parameter related 
> methods to both the KeyDerivationSpi and the KeyDerivation classes and 
> leave the getInstance() method alone....
>
> I'm sort of a don't care as long as I have a way of tweaking the KDF 
> before run the first derivation.
>
That's a good question, and one that I've been turning around in my head 
and don't (yet) have a great answer for, but we'll get there.

So my original prototype was based off KeyAgreement.java and the order 
obtaining the spi depends on the form of getInstance.  If it's a simple 
string-based algorithm form, then the provider is actually selected 
during the init method.  In the other two forms where a provider is 
specified as either a String or a Provider, the spi is obtained through 
the Provider object and therefore no init-time selection is needed.

We may need to have provider selection done a bit earlier since we're 
not only having to deal with the KDF itself, but a flavor of the KDF 
with the underlying PRF.  I need to find out a little bit of the history 
on why the provider selection happens during init for some of these 
APIs.  IIRC there was a reason to have delayed provider selection, but I 
don't have the history on that one.




More information about the security-dev mailing list