Draft design for Key Derivation API

Michael StJohns mstjohns at comcast.net
Sun Nov 19 20:15:40 UTC 2017


Sorry - I've been on travel for the last few days... comments below.

On 11/17/2017 10:48 AM, Adam Petcher wrote:
> On 11/17/2017 10:10 AM, Michael StJohns wrote:
>
>> On 11/16/2017 1:29 PM, Adam Petcher wrote:
>>> On 11/8/2017 6:50 PM, Michael StJohns wrote:
>>>
>>> What is the motivation behind this constructor that takes a byte 
>>> array? It seems like this constructor wouldn't actually help in a 
>>> hardware implementation. Would it be better to leave the 
>>> construction of this object to the implementation?
>>
>> This is a reasonable point, but misses a few things.   If you're 
>> calling the hardware implementation from software, you need to be 
>> able to pass data from the software domain to hardware domain.  If 
>> the KDF and the Object are both in hardware, then the provider 
>> implementation doesn't actually externalize the byte array from the 
>> KDF - it just returns the final pointer to the object.
>>
>> The hardware/software boundary has some unique challenges - mostly 
>> these are handled OK in the JCA.  For this particular model, you need 
>> to be able to move bits from software to hardware which is the point 
>> of the constructor as specified. For hardware to hardware it happens 
>> under the hood.  For hardware to software it may be prohibited (e.g. 
>> you can't actually externalize the bits of the key stream), but if 
>> its permitted then you need a simple way of translating key stream 
>> bytes into an object.
>
> That behavior all sounds reasonable, I just have doubts that this 
> belongs in the spec. Are you expecting KeyDerivation to contain the 
> logic in your last paragraph? Something like this:
>
> class KeyDerivation{
>   Object deriveObject() {
>     try {
>       return spi.deriveObject();
>     } catch (...) {
>       Class clazz = // get the class from the parameters
>       return clazz.newInstance(deriveData(), length); // shorthand for 
> getting the right ctor and calling it
>     }
>   }
> }
>
> I would expect something like that to happen in the KeyDerivationSpi 
> implementation instead, in which case it could construct the object 
> any way it wants. So the spec would not need to place any requirements 
> on the class of objects returned by deriveObject.
>

KDFs are somewhat problematic in that *_they may not necessarily be 
producing objects from their own provider_*. This unfortunately isn't 
obvious, but let me try and explain.

A KDF is basically a keyed pseudo-random number generator.  From the 
input key (and mixin context and label stuff) it produces a stream of 
bits.   Once that's done, the stream of bits is assigned to various 
output objects - secret keys, private keys, a byte array[] or a 
cryptographic object of some sort (cf TLS exporters for an example of 
this).  The current draft has an implicit assumption that the Key based 
objects will be formed from the current provider.  The byte array output 
is a providerless java.lang object.  The last type provides a model to 
allow for the production of objects not within the current provider.   
You *could* just punt on this and assume that you take the output of the 
deriveData() call and feed it to a factory of the other provider, but 
that means that the derivation production will necessarily be in the 
clear because the stream data will pass through the JVM.

Here's where it gets even trickier:

A given provider has a given security domain.  E.g. most software 
providers share the JVM memory domain.  HSM providers have a security 
domain representing pointers to objects within the HSM secure 
perimeter.  Mostly now, HSM providers do not share the same domains - 
but there are some cases where this might be possible and desirable 
(different providers leveraged on top the same HSM implementation, two 
SMs with a trusted path between them - TPMs and TEEPs for example).  I'd 
*really* like it if there is some way to keep  data from two different 
providers sharing the same or compatible security domains from having to 
pass their key stream data through the unsecure JVM memory domain.

Maybe there's a different way to do this - perhaps by changing the 
DeriviationParameterSpec to include the output provider?  But then you 
still need a way of generating non-key secure cryptographic objects I 
think....

Mike




-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/security-dev/attachments/20171119/9d48936f/attachment.html>


More information about the security-dev mailing list